From 79e81397b1bf90e6833db97e4944f8fe7801a669 Mon Sep 17 00:00:00 2001
From: Helius <wangdoubleone@gmail.com>
Date: Fri, 31 Jul 2020 17:04:24 +0800
Subject: [PATCH] add submit follower order
---
src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerOrderRelationDao.java | 3
src/main/java/com/xcong/excoin/modules/documentary/dao/FollowTraderInfoDao.java | 2
src/main/java/com/xcong/excoin/modules/documentary/service/FollowOrderOperationService.java | 13 ++
src/main/java/com/xcong/excoin/modules/documentary/service/impl/FollowOrderOperationServiceImpl.java | 199 +++++++++++++++++++++++++++++++++++++++
src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerSettingDao.java | 4
src/main/java/com/xcong/excoin/modules/documentary/common/NoticeConstant.java | 13 ++
src/main/resources/mapper/documentary/FollowFollowerSettingDao.xml | 7 +
src/main/resources/mapper/documentary/FollowTraderInfoDao.xml | 6 +
src/main/java/com/xcong/excoin/utils/LogRecordUtils.java | 20 +++
src/main/resources/mapper/documentary/FollowFollowerOrderRelationDao.xml | 8 +
10 files changed, 273 insertions(+), 2 deletions(-)
diff --git a/src/main/java/com/xcong/excoin/modules/documentary/common/NoticeConstant.java b/src/main/java/com/xcong/excoin/modules/documentary/common/NoticeConstant.java
new file mode 100644
index 0000000..aae8da4
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/documentary/common/NoticeConstant.java
@@ -0,0 +1,13 @@
+package com.xcong.excoin.modules.documentary.common;
+
+/**
+ * @author wzy
+ * @date 2020-07-31
+ **/
+public class NoticeConstant {
+
+ public static final String OPEN_ORDER_TITLE = "跟单开仓成功";
+
+ public static final String OPEN_ORDER_CONTENT = "{}开仓成功,开仓价{},交易员{}";
+
+}
diff --git a/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerOrderRelationDao.java b/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerOrderRelationDao.java
index dff3af5..a6c1a0e 100644
--- a/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerOrderRelationDao.java
+++ b/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerOrderRelationDao.java
@@ -2,9 +2,12 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xcong.excoin.modules.documentary.entity.FollowFollowerOrderRelationEntity;
+import io.lettuce.core.dynamic.annotation.Param;
/**
* @author helius
*/
public interface FollowFollowerOrderRelationDao extends BaseMapper<FollowFollowerOrderRelationEntity> {
+
+ Integer selectFollowerHoldingSymbolCnt(@Param("tradeMemberId") Long tradeMemberId, @Param("memberId") Long memberId);
}
diff --git a/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerSettingDao.java b/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerSettingDao.java
index aa057fc..f1c028a 100644
--- a/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerSettingDao.java
+++ b/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowFollowerSettingDao.java
@@ -5,6 +5,8 @@
import io.lettuce.core.dynamic.annotation.Param;
+import java.util.List;
+
/**
* @author helius
*/
@@ -13,4 +15,6 @@
FollowFollowerSettingEntity selectDocumentaryOrderSetInfoBymemberId(@Param("memberId")Long memberId);
FollowFollowerSettingEntity selectOneBymemberIdAndTradeId(@Param("memberId")Long memberId, @Param("traderId")Long traderId);
+
+ List<FollowFollowerSettingEntity> selectAllFollowerSettingByTradeMemberId(@Param("memberId") Long memberId);
}
diff --git a/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowTraderInfoDao.java b/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowTraderInfoDao.java
index 2e452cd..6daeec0 100644
--- a/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowTraderInfoDao.java
+++ b/src/main/java/com/xcong/excoin/modules/documentary/dao/FollowTraderInfoDao.java
@@ -9,4 +9,6 @@
FollowTraderInfoEntity selectFollowTraderInfoEntityBytreaderId(@Param("traderId")Long traderId);
+ FollowTraderInfoEntity selectTraderInfoByMemberId(@Param("memberId") Long memberId);
+
}
diff --git a/src/main/java/com/xcong/excoin/modules/documentary/service/FollowOrderOperationService.java b/src/main/java/com/xcong/excoin/modules/documentary/service/FollowOrderOperationService.java
new file mode 100644
index 0000000..2686947
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/documentary/service/FollowOrderOperationService.java
@@ -0,0 +1,13 @@
+package com.xcong.excoin.modules.documentary.service;
+
+
+import com.xcong.excoin.modules.contract.entity.ContractHoldOrderEntity;
+
+/**
+ * @author helius
+ */
+public interface FollowOrderOperationService {
+
+
+ public void addFollowerOrder(Long id);
+}
diff --git a/src/main/java/com/xcong/excoin/modules/documentary/service/impl/FollowOrderOperationServiceImpl.java b/src/main/java/com/xcong/excoin/modules/documentary/service/impl/FollowOrderOperationServiceImpl.java
new file mode 100644
index 0000000..93c91f9
--- /dev/null
+++ b/src/main/java/com/xcong/excoin/modules/documentary/service/impl/FollowOrderOperationServiceImpl.java
@@ -0,0 +1,199 @@
+package com.xcong.excoin.modules.documentary.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.xcong.excoin.common.enumerates.CoinTypeEnum;
+import com.xcong.excoin.common.enumerates.RabbitPriceTypeEnum;
+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.documentary.common.NoticeConstant;
+import com.xcong.excoin.modules.documentary.dao.FollowFollowerOrderRelationDao;
+import com.xcong.excoin.modules.documentary.dao.FollowFollowerProfitDao;
+import com.xcong.excoin.modules.documentary.dao.FollowFollowerSettingDao;
+import com.xcong.excoin.modules.documentary.dao.FollowTraderInfoDao;
+import com.xcong.excoin.modules.documentary.entity.FollowFollowerProfitEntity;
+import com.xcong.excoin.modules.documentary.entity.FollowFollowerSettingEntity;
+import com.xcong.excoin.modules.documentary.entity.FollowTraderInfoEntity;
+import com.xcong.excoin.modules.documentary.service.FollowOrderOperationService;
+import com.xcong.excoin.modules.member.dao.MemberDao;
+import com.xcong.excoin.modules.member.dao.MemberWalletContractDao;
+import com.xcong.excoin.modules.member.entity.AgentReturnEntity;
+import com.xcong.excoin.modules.member.entity.MemberEntity;
+import com.xcong.excoin.modules.member.entity.MemberWalletContractEntity;
+import com.xcong.excoin.modules.platform.entity.PlatformTradeSettingEntity;
+import com.xcong.excoin.rabbit.pricequeue.OrderModel;
+import com.xcong.excoin.rabbit.producer.OrderProducer;
+import com.xcong.excoin.utils.CacheSettingUtils;
+import com.xcong.excoin.utils.CalculateUtil;
+import com.xcong.excoin.utils.LogRecordUtils;
+import com.xcong.excoin.utils.ThreadPoolUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author helius
+ */
+@Slf4j
+@Service
+public class FollowOrderOperationServiceImpl implements FollowOrderOperationService {
+
+ @Resource
+ private ContractHoldOrderDao contractHoldOrderDao;
+ @Resource
+ private FollowFollowerSettingDao followFollowerSettingDao;
+ @Resource
+ private CacheSettingUtils cacheSettingUtils;
+ @Resource
+ private FollowFollowerOrderRelationDao followFollowerOrderRelationDao;
+ @Resource
+ private MemberWalletContractDao memberWalletContractDao;
+ @Resource
+ private MemberDao memberDao;
+ @Resource
+ private CommonService commonService;
+ @Resource
+ private ContractOrderDao contractOrderDao;
+ @Resource
+ private OrderProducer producer;
+ @Resource
+ private FollowTraderInfoDao followTraderInfoDao;
+
+ @Override
+ public void addFollowerOrder(Long id) {
+ // 查询交易员订单
+ ContractHoldOrderEntity holdOrderEntity = contractHoldOrderDao.selectById(id);
+
+ List<FollowFollowerSettingEntity> followerSettings = followFollowerSettingDao.selectAllFollowerSettingByTradeMemberId(holdOrderEntity.getMemberId());
+ // 开仓价
+ BigDecimal openPrice = holdOrderEntity.getOpeningPrice();
+ PlatformTradeSettingEntity tradeSettingEntity = cacheSettingUtils.getTradeSetting();
+
+ // 交易员信息
+ FollowTraderInfoEntity followTraderInfoEntity = followTraderInfoDao.selectTraderInfoByMemberId(holdOrderEntity.getMemberId());
+
+ // 点差
+ BigDecimal lotNumber = cacheSettingUtils.getSymbolSku(holdOrderEntity.getSymbol());
+ Long tradeMemberId = holdOrderEntity.getMemberId();
+ if (CollUtil.isNotEmpty(followerSettings)) {
+ for (FollowFollowerSettingEntity followerSetting : followerSettings) {
+ // 当前持仓张数
+ Integer holdingCnt = followFollowerOrderRelationDao.selectFollowerHoldingSymbolCnt(tradeMemberId, followerSetting.getMemberId());
+
+ // 跟单张数 根据跟随者设置,若为固定张数,则为其固定张数,若为固定比例,则与交易员张数相乘。但必须小于最大持仓张数
+ int symbolCnt = 0;
+ if (followerSetting.getFollowType().equals(FollowFollowerSettingEntity.FOLLOW_TYPE_PIECE)) {
+ symbolCnt = followerSetting.getFollowCnt();
+ } else {
+ symbolCnt = followerSetting.getFollowCnt() * holdOrderEntity.getSymbolCnt();
+ }
+
+ // 若张数+当前持仓张数大于最大持仓张数,则取最大持仓减去当前持仓,若差值小于等于0,则不下单
+ if (symbolCnt + holdingCnt> followerSetting.getMaxFollowCnt()) {
+ symbolCnt = followerSetting.getMaxFollowCnt() - holdingCnt;
+ }
+
+ if (symbolCnt <= 0) {
+ continue;
+ }
+
+ MemberWalletContractEntity walletContract = memberWalletContractDao.findWalletContractByMemberIdAndSymbol(followerSetting.getMemberId(), CoinTypeEnum.USDT.name());
+ if (walletContract == null) {
+ log.info("钱包地址不存在:{}", followerSetting.getMemberId());
+ continue;
+ }
+
+ // 开仓手续费 建仓价*规格*手数*手续费率
+ BigDecimal openFeePrice = openPrice.multiply(lotNumber)
+ .multiply(new BigDecimal(symbolCnt))
+ .multiply(tradeSettingEntity.getFeeRatio().divide(new BigDecimal(100)))
+ .setScale(8, BigDecimal.ROUND_DOWN);
+
+ // 保证金
+ BigDecimal bondAmount = openPrice.multiply(lotNumber).multiply(new BigDecimal(symbolCnt))
+ .multiply(BigDecimal.ONE.divide(new BigDecimal(holdOrderEntity.getLeverRatio())))
+ .setScale(8, BigDecimal.ROUND_DOWN);
+
+ // 预付款
+ BigDecimal prePaymentAmount = bondAmount.add(openFeePrice).add(openFeePrice);
+ if (prePaymentAmount.compareTo(walletContract.getAvailableBalance()) > -1) {
+ log.info("可用金额不足");
+ continue;
+ }
+
+ MemberEntity memberEntity = memberDao.selectById(followerSetting.getMemberId());
+ // 强平价
+ BigDecimal forceClosingPrice = CalculateUtil.getForceSetPrice(bondAmount, openPrice, symbolCnt, lotNumber, holdOrderEntity.getOpeningType(), memberEntity);
+
+ ContractHoldOrderEntity followHoldOrder = new ContractHoldOrderEntity();
+ followHoldOrder.setMemberId(memberEntity.getId());
+ followHoldOrder.setOrderNo(commonService.generateOrderNo(memberEntity.getId()));
+ followHoldOrder.setPositionType(ContractEntrustOrderEntity.POSITION_TYPE_ADD);
+ followHoldOrder.setTradeType(ContractHoldOrderEntity.TRADE_TYPE_MARK);
+ followHoldOrder.setSymbol(holdOrderEntity.getSymbol());
+ followHoldOrder.setSymbolCnt(symbolCnt);
+ followHoldOrder.setSymbolSku(lotNumber);
+ followHoldOrder.setLeverRatio(holdOrderEntity.getLeverRatio());
+ followHoldOrder.setForceClosingPrice(forceClosingPrice);
+ followHoldOrder.setOpeningFeeAmount(openFeePrice);
+ followHoldOrder.setOpeningPrice(openPrice);
+ followHoldOrder.setOpeningType(holdOrderEntity.getOpeningType());
+ followHoldOrder.setMarkPrice(openPrice);
+ followHoldOrder.setIsCanClosing(ContractHoldOrderEntity.ORDER_CAN_CLOSING_Y);
+ followHoldOrder.setPrePaymentAmount(prePaymentAmount);
+ followHoldOrder.setBondAmount(bondAmount.add(openFeePrice));
+ followHoldOrder.setOperateNo(1);
+ // 设置合约类型
+ holdOrderEntity.setContractType(ContractOrderEntity.CONTRACTTYPE_DOCUMENTARY);
+
+ ContractOrderEntity contractOrderEntity = ContractHoldOrderEntityMapper.INSTANCE.holdOrderToOrder(holdOrderEntity);
+ contractOrderEntity.setOpeningTime(new Date());
+ contractHoldOrderDao.insert(holdOrderEntity);
+ int i = contractOrderDao.insert(contractOrderEntity);
+
+ if (i > 0) {
+ memberWalletContractDao.increaseWalletContractBalanceById(prePaymentAmount.negate(), openFeePrice.negate(), null, walletContract.getId());
+
+ // 发送爆仓消息
+ sendOrderBombMsg(holdOrderEntity.getId(), holdOrderEntity.getOpeningType(), forceClosingPrice, holdOrderEntity.getSymbol(), holdOrderEntity.getOperateNo());
+
+ // 计算佣金
+ ThreadPoolUtils.calReturnMoney(memberEntity.getId(), contractOrderEntity.getOpeningFeeAmount(), contractOrderEntity, AgentReturnEntity.ORDER_TYPE_OPEN);
+
+ // 插入财务流水
+ if (holdOrderEntity.getOpeningType() == ContractHoldOrderEntity.OPENING_TYPE_MORE) {
+ LogRecordUtils.insertMemberAccountFlow(memberEntity.getId(), prePaymentAmount, walletContract.getAvailableBalance().subtract(prePaymentAmount), holdOrderEntity.getSymbol(), "买涨持仓", "买涨:" + holdOrderEntity.getSymbol());
+ LogRecordUtils.insertFollowerNotice(memberEntity.getId(), NoticeConstant.OPEN_ORDER_TITLE, StrUtil.format(NoticeConstant.OPEN_ORDER_CONTENT, holdOrderEntity.getSymbol() + "开多", openPrice, followTraderInfoEntity.getNickname()));
+ } else {
+ LogRecordUtils.insertMemberAccountFlow(memberEntity.getId(), prePaymentAmount, walletContract.getAvailableBalance().subtract(prePaymentAmount), holdOrderEntity.getSymbol(), "买跌持仓", "买跌:" + holdOrderEntity.getSymbol());
+ LogRecordUtils.insertFollowerNotice(memberEntity.getId(), NoticeConstant.OPEN_ORDER_TITLE, StrUtil.format(NoticeConstant.OPEN_ORDER_CONTENT, holdOrderEntity.getSymbol() + "开空", openPrice, followTraderInfoEntity.getNickname()));
+ }
+ }
+ }
+ }
+ }
+
+ public void sendOrderBombMsg(Long id, int type, BigDecimal forceClosingPrice, String symbol, int operateNo) {
+ OrderModel model = null;
+ // 开多
+ if (ContractHoldOrderEntity.OPENING_TYPE_MORE == type) {
+ model = new OrderModel(id, RabbitPriceTypeEnum.CLOSE_MORE_BOMB.getValue(), forceClosingPrice.setScale(8, RoundingMode.HALF_UP).toPlainString(), symbol, operateNo);
+ // 开空
+ } else {
+ model = new OrderModel(id, RabbitPriceTypeEnum.CLOSE_LESS_BOMB.getValue(), forceClosingPrice.setScale(8, RoundingMode.HALF_UP).toPlainString(), symbol, operateNo);
+ }
+ producer.sendPriceOperate(JSONObject.toJSONString(model));
+ }
+}
diff --git a/src/main/java/com/xcong/excoin/utils/LogRecordUtils.java b/src/main/java/com/xcong/excoin/utils/LogRecordUtils.java
index 6bf4189..1722f78 100644
--- a/src/main/java/com/xcong/excoin/utils/LogRecordUtils.java
+++ b/src/main/java/com/xcong/excoin/utils/LogRecordUtils.java
@@ -4,6 +4,8 @@
import com.xcong.excoin.modules.coin.dao.MemberAccountMoneyChangeDao;
import com.xcong.excoin.modules.coin.entity.MemberAccountFlowEntity;
import com.xcong.excoin.modules.coin.entity.MemberAccountMoneyChange;
+import com.xcong.excoin.modules.documentary.dao.FollowFollowerNoticeDao;
+import com.xcong.excoin.modules.documentary.entity.FollowFollowerNoticeEntity;
import java.math.BigDecimal;
@@ -15,7 +17,7 @@
**/
public class LogRecordUtils {
- public static void insertMemberAccountMoneyChange(Long memberId,String content, BigDecimal amount, String symbol, Integer status, Integer type) {
+ public static void insertMemberAccountMoneyChange(Long memberId, String content, BigDecimal amount, String symbol, Integer status, Integer type) {
MemberAccountMoneyChange accountRecord = new MemberAccountMoneyChange();
accountRecord.setContent(content);
accountRecord.setMemberId(memberId);
@@ -36,4 +38,20 @@
memberAccountFlowEntity.setRemark(remark);
SpringContextHolder.getBean(MemberAccountFlowEntityDao.class).insert(memberAccountFlowEntity);
}
+
+ /**
+ * 插入跟随者消息
+ *
+ * @param memberId 跟随者用户ID
+ * @param title 消息标题
+ * @param content 消息内容
+ */
+ public static void insertFollowerNotice(Long memberId, String title, String content) {
+ FollowFollowerNoticeEntity noticeEntity = new FollowFollowerNoticeEntity();
+ noticeEntity.setMemberId(memberId);
+ noticeEntity.setTitle(title);
+ noticeEntity.setContent(content);
+ SpringContextHolder.getBean(FollowFollowerNoticeDao.class).insert(noticeEntity);
+ }
+
}
diff --git a/src/main/resources/mapper/documentary/FollowFollowerOrderRelationDao.xml b/src/main/resources/mapper/documentary/FollowFollowerOrderRelationDao.xml
index c546474..f24dcfb 100644
--- a/src/main/resources/mapper/documentary/FollowFollowerOrderRelationDao.xml
+++ b/src/main/resources/mapper/documentary/FollowFollowerOrderRelationDao.xml
@@ -2,4 +2,12 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xcong.excoin.modules.documentary.dao.FollowFollowerOrderRelationDao">
+
+ <select id="selectFollowerHoldingSymbolCnt" resultType="java.lang.Integer">
+ select
+ IFNULL(sum(b.symbol_cnt),0)
+ from follow_follower_order_relation a, contract_hold_order b
+ where a.order_id=b.id and a.order_type=1 and a.trade_member_id=#{tradeMemberId}
+ and a.member_id=#{memberId}
+ </select>
</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/documentary/FollowFollowerSettingDao.xml b/src/main/resources/mapper/documentary/FollowFollowerSettingDao.xml
index d7a9724..eafdf2e 100644
--- a/src/main/resources/mapper/documentary/FollowFollowerSettingDao.xml
+++ b/src/main/resources/mapper/documentary/FollowFollowerSettingDao.xml
@@ -18,4 +18,11 @@
member_id = #{memberId}
and trader_id = #{traderId}
</select>
+
+
+ <select id="selectAllFollowerSettingByTradeMemberId" resultType="com.xcong.excoin.modules.documentary.entity.FollowFollowerSettingEntity">
+ select * from follow_follower_setting
+ where trader_member_id=#{memberId}
+ </select>
+
</mapper>
\ No newline at end of file
diff --git a/src/main/resources/mapper/documentary/FollowTraderInfoDao.xml b/src/main/resources/mapper/documentary/FollowTraderInfoDao.xml
index 268e65b..aee0491 100644
--- a/src/main/resources/mapper/documentary/FollowTraderInfoDao.xml
+++ b/src/main/resources/mapper/documentary/FollowTraderInfoDao.xml
@@ -5,5 +5,9 @@
<select id="selectFollowTraderInfoEntityBytreaderId" resultType="com.xcong.excoin.modules.documentary.entity.FollowTraderInfoEntity">
select * from follow_trader_info where id = #{traderId}
</select>
-
+
+
+ <select id="selectTraderInfoByMemberId" resultType="com.xcong.excoin.modules.documentary.entity.FollowTraderInfoEntity">
+ select * from follow_trader_info where member_id=#{memberId}
+ </select>
</mapper>
\ No newline at end of file
--
Gitblit v1.9.1