From 4bb0b890438349a7cfd7ab2dc30999346a5acf58 Mon Sep 17 00:00:00 2001
From: zj <1772600164@qq.com>
Date: Wed, 30 Apr 2025 01:18:10 +0800
Subject: [PATCH] 1

---
 src/main/java/com/nq/utils/task/stock/StockTask.java |  190 ++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 170 insertions(+), 20 deletions(-)

diff --git a/src/main/java/com/nq/utils/task/stock/StockTask.java b/src/main/java/com/nq/utils/task/stock/StockTask.java
index 08db5ed..ad227d2 100644
--- a/src/main/java/com/nq/utils/task/stock/StockTask.java
+++ b/src/main/java/com/nq/utils/task/stock/StockTask.java
@@ -1,6 +1,7 @@
 package com.nq.utils.task.stock;
 
 import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONArray;
 import com.alibaba.fastjson2.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -22,11 +23,13 @@
 import com.nq.service.impl.UserServiceImpl;
 import com.nq.utils.ConverterUtil;
 import com.nq.utils.KeyUtils;
+import com.nq.utils.UserPointUtil;
 import com.nq.utils.http.HttpClientRequest;
 import com.nq.utils.redis.RedisKeyConstant;
 import com.nq.utils.redis.RedisKeyUtil;
 import com.nq.utils.redis.RedisShardedPoolUtils;
 import com.nq.utils.stock.GeneratePosition;
+import com.nq.vo.position.PositionProfitVO;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -35,6 +38,7 @@
 import org.springframework.stereotype.Component;
 import org.springframework.web.client.RestTemplate;
 
+import javax.servlet.http.HttpServletRequest;
 import java.io.BufferedReader;
 import java.io.InputStreamReader;
 import java.io.UnsupportedEncodingException;
@@ -77,8 +81,6 @@
     @Autowired
     UserMapper userMapper;
 
-
-
     private static final Logger log = LoggerFactory.getLogger(StockTask.class);
 
 
@@ -118,31 +120,143 @@
                 pending();
             }catch (Exception e){
                 e.printStackTrace();
-                log.error("挂单定时任务报错:",e.getMessage());
+                log.error("买入挂单定时任务报错:",e.getMessage());
             }
             finally {
                 lock.unlock();  // 释放锁
             }
         } else {
             // 如果锁不可用,可以选择不执行或打印日志等
-            System.out.println("挂单定时任务  任务正在执行,跳过本次执行。");
+            System.out.println("买入挂单定时任务  任务正在执行,跳过本次执行。");
         }
     }
 
+    /**
+     * 挂单平仓
+     */
+    @Scheduled(cron = "0/10 * * * * ?")
+    public void closeOrder() {
+        ReentrantLock lock = new ReentrantLock();
+        if (lock.tryLock()) { // 尝试获取锁
+            try {
+                closeOutOrder();
+            }catch (Exception e){
+                e.printStackTrace();
+                log.error("平仓挂单定时任务报错:",e.getMessage());
+            }
+            finally {
+                lock.unlock();  // 释放锁
+            }
+        } else {
+            // 如果锁不可用,可以选择不执行或打印日志等
+            System.out.println("平仓挂单定时任务  任务正在执行,跳过本次执行。");
+        }
+    }
+
+    public void closeOutOrder() {
+        List<UserPendingorder> list = userPendingorderService.list(new LambdaQueryWrapper<>(UserPendingorder.class)
+                .eq(UserPendingorder::getPositionType, 1)
+                .eq(UserPendingorder::getHangingOrderType,2));
+        if(CollectionUtil.isNotEmpty(list)){
+            list.forEach(f->{
+                //获取当前价格
+                //股票类型 现价 数据源的处理
+                BigDecimal nowPrice = BigDecimal.ZERO;
+                if(f.getStockType().equals("ST")){
+                    nowPrice = priceServices.getNowPrice(f.getStockCode());
+                }else{
+                    nowPrice = new BigDecimal(RedisShardedPoolUtils.get(RedisKeyConstant.getRedisKey(f.getStockName())));
+                }
+                if((f.getOrderDirection().equals("买涨") && nowPrice.compareTo(f.getSellOrderPrice()) >= 0) || (f.getOrderDirection().equals("买跌") && nowPrice.compareTo(f.getSellOrderPrice()) <= 0)){
+                    closeStockTransferPositions(f);
+                }
+            });
+        }
+    }
+
+    private void closeStockTransferPositions(UserPendingorder f) {
+        UserPosition userPosition = userPositionMapper.selectOne(new LambdaQueryWrapper<>(UserPosition.class)
+                .eq(UserPosition::getPositionSn, f.getPositionSn())
+                .eq(UserPosition::getUserId, f.getUserId())
+
+        );
+
+        BigDecimal siitteBuyFee = new BigDecimal(iStockConfigServices.queryByKey(EConfigKey.SELL_HANDLING_CHARGE.getCode()).getCValue());
+        //部分平仓
+        if(f.getOrderNum() < userPosition.getOrderNum()){
+            //拆分订单
+            UserPosition position = ConverterUtil.convert(userPosition,UserPosition.class);
+            position.setId(null);
+            position.setPositionSn(KeyUtils.getUniqueKey());
+            //得到均价
+            double buyOrderPrice = position.getOrderTotalPrice().doubleValue() / position.getOrderNum().doubleValue() * position.getOrderLever();
+            position.setOrderNum(userPosition.getOrderNum()-f.getOrderNum());
+            BigDecimal positionBuyAmt = new BigDecimal(buyOrderPrice).multiply(new BigDecimal(position.getOrderNum())).divide(new BigDecimal(position.getOrderLever()));
+            position.setOrderTotalPrice(positionBuyAmt);
+            position.setBuyOrderPrice(new BigDecimal(buyOrderPrice));
+            position.setBuyOrderId(GeneratePosition.getPositionId());
+            //修改拆分订单手续费
+            BigDecimal BuyFee = new BigDecimal(iStockConfigServices.queryByKey(EConfigKey.BUY_HANDLING_CHARGE.getCode()).getCValue());
+            BigDecimal buyPrice = position.getBuyOrderPrice().multiply(new BigDecimal(position.getOrderNum()));
+            BigDecimal xsPrice = buyPrice.multiply(BuyFee);
+            position.setOrderFee(xsPrice);
+            userPositionMapper.insert(position);
+            //得到均价
+            double orderPrice = userPosition.getOrderTotalPrice().doubleValue() / userPosition.getOrderNum().doubleValue() * position.getOrderLever();
+            //修改原订单
+            userPosition.setOrderNum(f.getOrderNum());
+            BigDecimal buyAmt = new BigDecimal(orderPrice).multiply(new BigDecimal(userPosition.getOrderNum())).divide(new BigDecimal(userPosition.getOrderLever()));
+            userPosition.setOrderTotalPrice(buyAmt);
+            userPosition.setOrderFee(userPosition.getOrderFee().subtract(position.getOrderFee()));
+            userPositionMapper.updateById(userPosition);
+        }
+        getObjectServerResponse(userPosition, f.getSellOrderPrice(), siitteBuyFee, f.getStockType());
+        f.setPositionType(2);
+        userPendingorderService.updateById(f);
+    }
+
+    public void getObjectServerResponse( UserPosition userPosition, BigDecimal nowPrice, BigDecimal siitteBuyFee, String stockType) {
+        userPosition.setSellOrderId(GeneratePosition.getPositionId());
+        userPosition.setSellOrderPrice(nowPrice);
+        userPosition.setSellOrderTime(new Date());
+
+        BigDecimal sellOrderTotel = nowPrice.multiply(new BigDecimal(userPosition.getOrderNum()));
+        BigDecimal xsPrice = sellOrderTotel.multiply(siitteBuyFee);
+        userPosition.setOrderFee(userPosition.getOrderFee().add(xsPrice));
+        userPositionMapper.updateById(userPosition);
+
+        iUserAssetsServices.availablebalanceChange(stockType,
+                userPosition.getUserId(),
+                EUserAssets.CLOSE_POSITION_RETURN_SECURITY_DEPOSIT,
+                userPosition.getOrderTotalPrice(), "", "");
+        iUserAssetsServices.availablebalanceChange(stockType,
+                userPosition.getUserId(), EUserAssets.HANDLING_CHARGE,
+                xsPrice, "", "");
+
+        PositionProfitVO profitVO = UserPointUtil.getPositionProfitVO(userPosition,
+                priceServices.getNowPrice(userPosition.getStockCode()));
+
+        iUserAssetsServices.availablebalanceChange(stockType,
+                userPosition.getUserId(), EUserAssets.CLOSE_POSITION,
+                profitVO.getAllProfitAndLose(), "", "");
+    }
+
     public void pending(){
-        List<UserPendingorder> list = userPendingorderService.list(new LambdaQueryWrapper<>(UserPendingorder.class).eq(UserPendingorder::getPositionType, 1));
+        List<UserPendingorder> list = userPendingorderService.list(new LambdaQueryWrapper<>(UserPendingorder.class)
+                .eq(UserPendingorder::getPositionType, 1)
+                .eq(UserPendingorder::getHangingOrderType,1));
         if(CollectionUtil.isNotEmpty(list)){
             list.forEach(f->{
                 if(f.getStockGid().equals("ST")){
                     //获取当前价格
                     //股票类型 现价 数据源的处理
                     BigDecimal nowPrice = priceServices.getNowPrice(f.getStockCode());
-                    if(f.getBuyOrderPrice().compareTo(nowPrice) <= 0){
+                    if((f.getOrderDirection().equals("买涨") && f.getBuyOrderPrice().compareTo(nowPrice) >= 0) || (f.getOrderDirection().equals("买跌") && f.getBuyOrderPrice().compareTo(nowPrice) <= 0)){
                         stockTransferPositions(f);
                     }
                 }else{
                     String price = RedisShardedPoolUtils.get(RedisKeyConstant.getRedisKey(f.getStockName()));
-                    if(f.getBuyOrderPrice().compareTo(new BigDecimal(price)) <= 0){
+                    if((f.getOrderDirection().equals("买涨") && f.getBuyOrderPrice().compareTo(new BigDecimal(price)) >= 0) || (f.getOrderDirection().equals("买跌") && f.getBuyOrderPrice().compareTo(new BigDecimal(price)) <= 0)){
                         hjTransferPositions(f);
                     }
                 }
@@ -150,31 +264,67 @@
         }
     }
     public void hjTransferPositions(UserPendingorder userPendingorder){
+        UserPosition position = userPositionMapper.selectOne(new LambdaQueryWrapper<>(UserPosition.class)
+                .eq(UserPosition::getUserId, userPendingorder.getUserId())
+                .eq(UserPosition::getStockCode, userPendingorder.getStockCode())
+                .isNull(UserPosition::getSellOrderId)
+        );
         User user = userMapper.selectById(userPendingorder.getUserId());
         BigDecimal siteSettingBuyFee = new BigDecimal(iStockConfigServices.queryByKey(EConfigKey.BUY_HANDLING_CHARGE.getCode()).getCValue()) ;
         BigDecimal orderFree = siteSettingBuyFee.multiply(userPendingorder.getOrderTotalPrice());
         UserPosition userPosition = ConverterUtil.convert(userPendingorder, UserPosition.class);
-        userPosition.setPositionType(user.getAccountType());
-        userPosition.setId(null);
-        userPendingorder.setPositionType(0);
-        userPendingorderService.updateById(userPendingorder);
-        userPositionMapper.insert(userPosition);
-        iUserAssetsServices.availablebalanceChange("USDT", user.getId(), EUserAssets.HANDLING_CHARGE, orderFree, "", "");
+        if(ObjectUtil.isEmpty(position)){
+            userPosition.setPositionType(user.getAccountType());
+            userPosition.setId(null);
+            userPendingorder.setPositionType(0);
+            userPendingorderService.updateById(userPendingorder);
+            userPositionMapper.insert(userPosition);
+            iUserAssetsServices.availablebalanceChange("USD", user.getId(), EUserAssets.HANDLING_CHARGE, orderFree, "", "");
+        }else{
+            position.setOrderNum(position.getOrderNum()+userPosition.getOrderNum());
+            position.setOrderTotalPrice(position.getOrderTotalPrice().add(userPosition.getOrderTotalPrice()));
+            position.setOrderFee(position.getOrderFee().add(orderFree));
+            position.setBuyOrderPrice(position.getBuyOrderPrice());
+            position.setAllProfitAndLose(position.getAllProfitAndLose().add(orderFree));
+            userPositionMapper.updateById(position);
+            userPendingorder.setPositionType(0);
+            userPendingorderService.updateById(userPendingorder);
+            iUserAssetsServices.availablebalanceChange("USD", user.getId(), EUserAssets.HANDLING_CHARGE, orderFree, "", "");
+        }
     }
 
     public void stockTransferPositions(UserPendingorder userPendingorder){
+        UserPosition position = userPositionMapper.selectOne(new LambdaQueryWrapper<>(UserPosition.class)
+                .eq(UserPosition::getUserId, userPendingorder.getUserId())
+                .eq(UserPosition::getStockCode, userPendingorder.getStockCode())
+                .isNull(UserPosition::getSellOrderId)
+        );
         // 手续费率
         BigDecimal siteSettingBuyFee = new BigDecimal(iStockConfigServices.queryByKey(EConfigKey.BUY_HANDLING_CHARGE.getCode()).getCValue()) ;
         BigDecimal orderFree = siteSettingBuyFee.multiply(userPendingorder.getOrderTotalPrice());
         User user = userMapper.selectById(userPendingorder.getUserId());
         UserPosition userPosition = ConverterUtil.convert(userPendingorder, UserPosition.class);
-        userPosition.setPositionType(user.getAccountType());
-        userPosition.setId(null);
-        userPendingorder.setPositionType(0);
-        userPendingorderService.updateById(userPendingorder);
-        userPositionMapper.insert(userPosition);
-        //挂单成功扣除手续费
-        iUserAssetsServices.availablebalanceChange("ST", user.getId(), EUserAssets.HANDLING_CHARGE, orderFree, "", "");
+        if(ObjectUtil.isEmpty(position)){
+            userPosition.setPositionType(user.getAccountType());
+            userPosition.setId(null);
+            userPendingorder.setPositionType(0);
+            userPendingorderService.updateById(userPendingorder);
+            userPositionMapper.insert(userPosition);
+            //挂单成功扣除手续费
+            iUserAssetsServices.availablebalanceChange("ST", user.getId(), EUserAssets.HANDLING_CHARGE, orderFree, "", "");
+        }else{
+            position.setOrderNum(position.getOrderNum()+userPosition.getOrderNum());
+            position.setOrderTotalPrice(position.getOrderTotalPrice().add(userPosition.getOrderTotalPrice()));
+            position.setOrderFee(position.getOrderFee().add(orderFree));
+            double divide = position.getOrderTotalPrice().doubleValue() / position.getOrderNum();
+            position.setBuyOrderPrice(new BigDecimal(divide*position.getOrderLever()));
+            position.setAllProfitAndLose(position.getAllProfitAndLose().add(orderFree));
+            userPositionMapper.updateById(position);
+            userPendingorder.setPositionType(0);
+            userPendingorderService.updateById(userPendingorder);
+            //挂单成功扣除手续费
+            iUserAssetsServices.availablebalanceChange("ST", user.getId(), EUserAssets.HANDLING_CHARGE, orderFree, "", "");
+        }
     }
 
     //最新价格url

--
Gitblit v1.9.3