From 92310aaa56ae040c9147f6495630f2c1ae41fac2 Mon Sep 17 00:00:00 2001
From: zj <1772600164@qq.com>
Date: Fri, 26 Apr 2024 10:21:05 +0800
Subject: [PATCH] 1

---
 src/main/java/com/nq/service/impl/UserPositionServiceImpl.java |  174 ++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 150 insertions(+), 24 deletions(-)

diff --git a/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java b/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
index 67784f6..cfc0742 100644
--- a/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
+++ b/src/main/java/com/nq/service/impl/UserPositionServiceImpl.java
@@ -1,5 +1,6 @@
 package com.nq.service.impl;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.nq.dao.*;
 import com.nq.enums.EConfigKey;
@@ -119,7 +120,7 @@
         SiteProduct siteProduct = iSiteProductService.getProductSetting();
 
         User user = this.iUserService.getCurrentRefreshUser(request);
-        if (siteProduct.getRealNameDisplay() && (StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCard()))) {
+        if (siteProduct.getRealNameDisplay() && user.getIsActive() != 2) {
             return ServerResponse.createByErrorMsg("订单失败,请先实名认证", request);
         }
         // 手续费率
@@ -170,14 +171,14 @@
             return ServerResponse.createByErrorMsg("报价0,请稍后再试", request);
         }
 
-        BigDecimal buyAmt = nowPrice.multiply(new BigDecimal(buyNum));
+        BigDecimal buyAmt = nowPrice.multiply(new BigDecimal(buyNum)).divide(new BigDecimal(lever));
         BigDecimal orderFree = siteSettingBuyFee.multiply(buyAmt);
 
         UserAssets userAssets = iUserAssetsServices.assetsByTypeAndUserId(stock.getStockType(), user.getId());
         BigDecimal   fundratio = new BigDecimal(user.getFundRatio()).divide(new BigDecimal(100));
         BigDecimal availableBalance =  fundratio.multiply(userAssets.getAvailableBalance());
         if (availableBalance.compareTo(buyAmt.add(orderFree)) < 0) {
-            return ServerResponse.createByErrorMsg("订单失败,余额不足", request);
+            return ServerResponse.createByErrorMsg("订单失败,配资不足", request);
         }
         UserPosition userPosition = new UserPosition();
         if (profitTarget != null && profitTarget.compareTo(new BigDecimal("0")) > 0) {
@@ -315,7 +316,9 @@
     @Transactional
     public ServerResponse sell(String positionSn, int doType, HttpServletRequest request) {
         UserPosition userPosition = this.userPositionMapper.findPositionBySn(positionSn);
-        BigDecimal siitteBuyFee = iSiteSettingService.getSiteSetting().getBuyFee();
+        // 手续费率
+        BigDecimal siitteBuyFee = new BigDecimal(iStockConfigServices.queryByKey(EConfigKey.SELL_HANDLING_CHARGE.getCode()).getCValue()) ;
+
         Boolean b = tradingHourService.timeCheck(userPosition.getStockCode());
         if (!b) {
             return ServerResponse.createByErrorMsg("订单失败,不在交易时间之内", request);
@@ -335,7 +338,7 @@
         }
         Stock stock = stockMapper.selectOne(new QueryWrapper<Stock>().eq("stock_code", userPosition.getStockCode()));
         if (!priceServices.isLimitDownSell(stock.getStockCode())) {
-            return ServerResponse.createByErrorMsg("股票垫停,无法平仓", request);
+            return ServerResponse.createByErrorMsg("股票跌停,无法平仓", request);
         }
         BigDecimal nowPrice = priceServices.getNowPrice(userPosition.getStockCode());
         if (nowPrice.compareTo(new BigDecimal("0")) != 1) {
@@ -358,6 +361,7 @@
 
         PositionProfitVO profitVO = UserPointUtil.getPositionProfitVO(userPosition,
                 priceServices.getNowPrice(userPosition.getStockCode()));
+
         userAssetsServices.availablebalanceChange(stock.getStockType(),
                 userPosition.getUserId(), EUserAssets.CLOSE_POSITION,
                 profitVO.getAllProfitAndLose(), "", "");
@@ -1151,24 +1155,23 @@
         if (userStockSubscribe == null) {
             return ServerResponse.createByErrorMsg("无该申购记录");
         }
-        StockSubscribe stockSubscribe = stockSubscribeMapper.selectOne(new QueryWrapper<StockSubscribe>().eq("code", userStockSubscribe.getNewCode()));
+        StockSubscribe stockSubscribe = stockSubscribeMapper.selectOne(new QueryWrapper<StockSubscribe>().eq("code", userStockSubscribe.getNewCode()).eq("type",userStockSubscribe.getType()));
         if (userStockSubscribe == null) {
             return ServerResponse.createByErrorMsg("该新股不存在");
         }
         if (userStockSubscribe.getStatus() == 4 || userStockSubscribe.getStatus() == 3 && stockSubscribe.getType() == 2) {
-
-//                String sinaStock = SinaStockApi.getSinaStock(stockSubscribe.getStockType()+userStockSubscribe.getNewCode());
-//                String[] arrayOfString = sinaStock.split(",");
-//                 if (arrayOfString.length < 10){
-//                 return ServerResponse.createByErrorMsg("数据源无该新股数据,转持仓失败");
-//                 }
+            Stock stock = stockMapper.selectOne(new LambdaQueryWrapper<Stock>().eq(Stock::getStockSpell, userStockSubscribe.getNewCode()));
+            if(null == stock){
+                return ServerResponse.createByErrorMsg("该新股不存在");
+            }
             UserPosition userPosition = new UserPosition();
             userPosition.setPositionType(1);
             userPosition.setPositionSn(KeyUtils.getUniqueKey());
             userPosition.setUserId(userStockSubscribe.getUserId());
             userPosition.setNickName(userStockSubscribe.getRealName());
             userPosition.setAgentId(userStockSubscribe.getAgentId());
-            userPosition.setStockCode(userStockSubscribe.getNewCode());
+            userPosition.setStockCode(stock.getStockCode());
+            userPosition.setStockSpell(stock.getStockSpell());
             userPosition.setStockName(userStockSubscribe.getNewName());
             userPosition.setStockGid(stockSubscribe.getStockType() + userStockSubscribe.getNewCode());
 
@@ -1205,14 +1208,6 @@
             log.info("用户购买印花税(配资后总资金 * 百分比) = {}", buy_yhs_amt);
             userPosition.setOrderSpread(buy_yhs_amt);
 
-            //            SiteSpread siteSpread = iSiteSpreadService.findSpreadRateOne(new BigDecimal(stock_crease), buy_amt, stock.getStockCode(), now_price);
-            //            BigDecimal spread_rate_amt = new BigDecimal("0");
-            //            if(siteSpread != null){
-            //                spread_rate_amt = buy_amt.multiply(siteSpread.getSpreadRate()).setScale(2, 4);
-            //                log.info("用户购买点差费(配资后总资金 * 百分比{}) = {}", siteSpread.getSpreadRate(), spread_rate_amt);
-            //            } else{
-            //                log.info("用户购买点差费(配资后总资金 * 百分比{}) = {}", "设置异常", spread_rate_amt);
-            //            }
             BigDecimal spread_rate_amt = new BigDecimal(0);
             userPosition.setSpreadRatePrice(spread_rate_amt);
 
@@ -1236,7 +1231,7 @@
                 userStockSubscribeMapper.update1(userStockSubscribe);
                 if (userStockSubscribe.getType() == 1 || userStockSubscribe.getType() == 2) {
                     User user = userMapper.selectById(userStockSubscribe.getUserId());
-                    ret = userMapper.updateByPrimaryKey(user);
+                    ret = userMapper.updateById(user);
                 }
                 if (ret > 0) {
                     return ServerResponse.createBySuccessMsg("新股转持仓成功");
@@ -1535,7 +1530,7 @@
         //价格处理
         Stock stock = stockMapper.selectOne(new QueryWrapper<Stock>().eq("stock_code", stockDz.getStockCode()));
 
-        if(stockDz.getStartTime().after(new Date()) || stockDz.getEndTime().after(new Date())){
+        if(stockDz.getStartTime().getTime() > new Date().getTime() || stockDz.getEndTime().getTime() < new Date().getTime()){
             return ServerResponse.createByErrorMsg("不在大宗交易所时间之内", request);
         }
         BigDecimal nowPrice = priceServices.getNowPrice(stockCode).multiply(stockDz.getDiscount());
@@ -1551,7 +1546,7 @@
         BigDecimal   fundratio = new BigDecimal(user.getFundRatio()).divide(new BigDecimal(100));
         BigDecimal availableBalance =  fundratio.multiply(userAssets.getAvailableBalance());
         if (buyAmt.compareTo(availableBalance) > 0) {
-            return ServerResponse.createByErrorMsg("订单失败,余额不足", request);
+            return ServerResponse.createByErrorMsg("订单失败,配资不足", request);
         }
         UserPosition userPosition = new UserPosition();
         userPosition.setPositionType(3);
@@ -1599,6 +1594,137 @@
 
     }
 
+    @Override
+    @Transactional
+    public void stockConstraint(List<UserPosition> list) {
+        SiteSetting siteSetting = iSiteSettingService.getSiteSetting();
+        BigDecimal siteBuyFee = siteSetting.getBuyFee();
+
+        for (UserPosition position : list) {
+            //平仓检查
+            Result result = getResult(position);
+            if (result == null) continue;
+
+            //利润为0不需要进行强制平仓
+            if(result.signum == 0){
+                continue;
+            }
+            boolean liquidation = false;
+            liquidation = isLiquidation(position, result.signum, result.profit, liquidation);
+            if(liquidation){
+                extracted(position, result.nowPrice, result.stock);
+            }
+        }
+    }
+
+    private Result getResult(UserPosition position) {
+        // 检查订单是否存在
+        if (position == null) {
+            log.info("订单不存在,订单id: {}", position.getId());
+            return null;
+        }
+
+        // 检查用户是否存在
+        User user = this.userMapper.selectById(position.getUserId());
+        if (user == null) {
+            log.info("用户不存在,订单id: {}", position.getId());
+            return null;
+        }
+
+        // 检查是否在交易时间内
+        if (!tradingHourService.timeCheck(position.getStockCode())) {
+            log.info("不在交易时间之内,订单id: {}", position.getId());
+            return null;
+        }
+
+        //判断订单
+        if (1 == position.getIsLock().intValue()) {
+            log.info("订单已终止,订单id: {}", position.getId());
+            return null;
+        }
+
+        // 检查股票是否垫停
+        Stock stock = stockMapper.selectOne(new QueryWrapper<Stock>().eq("stock_code", position.getStockCode()));
+        if (!priceServices.isLimitDownSell(stock.getStockCode())) {
+            log.info("股票跌停,无法平仓,订单id: {}", position.getId());
+            return null;
+        }
+
+        //最新报价
+        BigDecimal nowPrice = priceServices.getNowPrice(position.getStockCode());
+        if (nowPrice.compareTo(BigDecimal.ZERO) <= 0) {
+            log.info("报价0,平仓失败,订单id: {}", position.getId());
+            return null;
+        }
+
+        //判断订单是否已到强制平仓价格
+        BigDecimal purchaseAmount = position.getBuyOrderPrice().multiply(new BigDecimal(position.getOrderNum()));// 买入价总额
+        BigDecimal nowPriceAmount = nowPrice.multiply(new BigDecimal(position.getOrderNum())); // 现价总额
+
+        BigDecimal profit = nowPriceAmount.subtract(purchaseAmount);//利润
+        int signum = profit.signum();  // -1, 0, 1,分别表示 负数、零、正数
+        Result result = new Result(stock, nowPrice, profit, signum);
+        return result;
+    }
+
+    private static class Result {
+        public final Stock stock;//股票
+        public final BigDecimal nowPrice;//现价
+        public final BigDecimal profit;//利润
+        public final int signum;// -1, 0, 1,分别表示 负数、零、正数
+
+        public Result(Stock stock, BigDecimal nowPrice, BigDecimal profit, int signum) {
+            this.stock = stock;
+            this.nowPrice = nowPrice;
+            this.profit = profit;
+            this.signum = signum;
+        }
+    }
+
+    //判断平仓
+    private static boolean isLiquidation(UserPosition position, int signum, BigDecimal profit, boolean liquidation) {
+        if(position.getOrderDirection().equals("买涨")){
+            //如果买涨 signum 为-1则表示亏损
+            if(signum == -1){
+                //判断亏损金额是否达到保证金金额
+                BigDecimal negate = profit.negate();
+                if (negate.compareTo(position.getOrderTotalPrice()) >= 0){
+                    //强制平仓
+                    liquidation = true;
+                }
+            }
+        }else{
+            //买跌 signum
+            if(signum == 1){
+                //判断亏损金额是否达到保证金金额
+                if (profit.compareTo(position.getOrderTotalPrice()) >= 0){
+                    //强制平仓
+                    liquidation = true;
+                }
+            }
+        }
+        return liquidation;
+    }
+
+    //平仓
+    private void extracted(UserPosition position, BigDecimal nowPrice, Stock stock) {
+        // 更新订单信息
+        position.setSellOrderId(GeneratePosition.getPositionId());
+        position.setSellOrderPrice(nowPrice);
+        position.setSellOrderTime(new Date());
+        userPositionMapper.updateById(position);
+
+        // 计算手续费等
+        BigDecimal handlingFee = BigDecimal.ZERO;
+
+        //更新用户资产
+        userAssetsServices.availablebalanceChange(stock.getStockType(),
+                position.getUserId(),
+                EUserAssets.CONSTRAINT_CLOSE_POSITION,
+                position.getOrderTotalPrice(), "", "");
+        log.info("强制平仓成功,订单id: {}", position.getId());
+    }
+
 }
 
 

--
Gitblit v1.9.3