| | |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | | |
| | | import cn.hutool.core.util.ObjectUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.StringUtils; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | |
| | | import com.nq.vo.foreigncurrency.ExchangeVO; |
| | | import com.nq.vo.position.UserPendingorderVO; |
| | | import com.nq.vo.stock.MarketVO; |
| | | import com.nq.vo.stock.PremarketStockVO; |
| | | import com.nq.vo.stock.StockListVO; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | |
| | | |
| | | @Autowired |
| | | private UserPositionMapper userPositionMapper; |
| | | |
| | | @Autowired |
| | | IStockService iStockService; |
| | | |
| | | @Override |
| | | @org.springframework.transaction.annotation.Transactional(rollbackFor = Exception.class) |
| | |
| | | |
| | | // 创建挂单记录 |
| | | UserPendingorder userPendingorder = new UserPendingorder(); |
| | | userPendingorder.setUserId(user.getId()); |
| | | userPendingorder.setStockId(stockId); |
| | | userPendingorder.setBuyNum(buyNum); |
| | | userPendingorder.setBuyType(buyType); |
| | | userPendingorder.setLever(lever); |
| | | userPendingorder.setProfitTarget(profitTarget); |
| | | userPendingorder.setStopTarget(stopTarget); |
| | | userPendingorder.setNowPrice(new BigDecimal(0)); |
| | | userPendingorder.setTargetPrice(targetPrice); |
| | | userPendingorder.setAddTime(new Date()); |
| | | userPendingorder.setStatus(0); |
| | | userPendingorder.setUserId(user.getId()); |
| | | userPendingorder.setStockId(stockId); |
| | | userPendingorder.setBuyNum(buyNum); |
| | | userPendingorder.setBuyType(buyType); |
| | | userPendingorder.setLever(lever); |
| | | userPendingorder.setProfitTarget(profitTarget); |
| | | userPendingorder.setStopTarget(stopTarget); |
| | | userPendingorder.setNowPrice(new BigDecimal(0)); |
| | | userPendingorder.setTargetPrice(targetPrice); |
| | | userPendingorder.setAddTime(new Date()); |
| | | userPendingorder.setStatus(0); |
| | | |
| | | int ret = userPendingorderMapper.insert(userPendingorder); |
| | | if (ret > 0) { |
| | | int ret = userPendingorderMapper.insert(userPendingorder); |
| | | if (ret > 0) { |
| | | // 冻结资金 |
| | | iUserAssetsServices.availablebalanceChange(stock.getStockType(), user.getId(), |
| | | com.nq.enums.EUserAssets.PENDING_ORDER_FREEZE, needFreezeAmt.negate(), "挂单冻结资金", ""); |
| | |
| | | // 查询所有待处理的挂单 |
| | | List<UserPendingorder> userPendingorders = userPendingorderMapper.selectList(new QueryWrapper<UserPendingorder>().eq("status", 0)); |
| | | log.info("当前有挂单数量:{}", userPendingorders.size()); |
| | | |
| | | for (UserPendingorder userPendingorder : userPendingorders) { |
| | | |
| | | |
| | | |
| | | List<PremarketStockVO> premarketStock = iStockService.getPremarketStock(); |
| | | |
| | | Map<String, PremarketStockVO> stockMap = premarketStock.stream() |
| | | .collect(Collectors.toMap( |
| | | PremarketStockVO::getCode, |
| | | stock -> stock |
| | | )); |
| | | |
| | | |
| | | orderLoop: for (UserPendingorder userPendingorder : userPendingorders) { |
| | | try { |
| | | // 参数校验 |
| | | if (userPendingorder.getUserId() == null || userPendingorder.getStockId() == null |
| | | || userPendingorder.getBuyNum() == null || userPendingorder.getBuyType() == null |
| | | || userPendingorder.getLever() == null || userPendingorder.getTargetPrice() == null) { |
| | | continue; |
| | | } |
| | | continue; |
| | | } |
| | | |
| | | // 获取股票信息 |
| | | Stock stock = stockMapper.findStockByCode(userPendingorder.getStockId()); |
| | |
| | | log.error("挂单转持仓失败,股票不存在:{}", userPendingorder.getStockId()); |
| | | userPendingorder.setStatus(2); |
| | | this.userPendingorderMapper.updateById(userPendingorder); |
| | | continue; |
| | | } |
| | | |
| | | continue; |
| | | } |
| | | PremarketStockVO p = stockMap.get(stock.getStockCode()); |
| | | // 获取当前价格 |
| | | BigDecimal nowPrice = priceServices.getNowPrice(stock.getStockCode()); |
| | | if (nowPrice.compareTo(BigDecimal.ZERO) == 0) { |
| | | continue; |
| | | } |
| | | if(ObjectUtil.isEmpty(p)){ |
| | | |
| | | // 判断价格是否达到目标价格:当前价格 <= 挂单价就买入 |
| | | if (nowPrice.compareTo(userPendingorder.getTargetPrice()) > 0) { |
| | | // 当前价格大于挂单价,继续等待 |
| | | continue; |
| | | } |
| | | if (nowPrice.compareTo(BigDecimal.ZERO) == 0) { |
| | | continue; |
| | | } |
| | | |
| | | // 价格达到目标价格,执行买入逻辑 |
| | | synchronized (userPendingorder.getUserId()) { |
| | | // 判断价格是否达到目标价格:当前价格 <= 挂单价就买入 |
| | | if (nowPrice.compareTo(userPendingorder.getTargetPrice()) > 0) { |
| | | // 当前价格大于挂单价,继续等待 |
| | | continue; |
| | | } |
| | | |
| | | // 价格达到目标价格,先进行验证 |
| | | // 判断股票是否在可交易时间段 |
| | | Boolean b = tradingHourService.timeCheck(stock.getStockCode(), stock.getStockType()); |
| | | if (!b) { |
| | | continue; |
| | | } |
| | | |
| | | // 检查股票是否被锁定 |
| | | if (stock.getIsLock() != 0) { |
| | | log.info("挂单转持仓失败,股票被锁定:{}", stock.getStockCode()); |
| | | userPendingorder.setStatus(2); |
| | | this.userPendingorderMapper.updateById(userPendingorder); |
| | | }else{ |
| | | // 判断价格是否达到目标价格:当前价格 <= 挂单价就买入 |
| | | if (p.getPrice().compareTo(userPendingorder.getTargetPrice()) > 0) { |
| | | // 当前价格大于挂单价,继续等待 |
| | | continue; |
| | | } |
| | | nowPrice = p.getPrice(); |
| | | } |
| | | |
| | | // 检查是否有配额 |
| | | if (!priceServices.isLimitUpBuy(stock.getStockCode())) { |
| | | continue; |
| | | } |
| | | |
| | | // 获取用户信息 |
| | | User user = this.userMapper.selectById(userPendingorder.getUserId()); |
| | | if (user == null) { |
| | | continue; |
| | | // 检查股票是否被锁定 |
| | | if (stock.getIsLock() != 0) { |
| | | log.info("挂单转持仓失败,股票被锁定:{}", stock.getStockCode()); |
| | | userPendingorder.setStatus(2); |
| | | this.userPendingorderMapper.updateById(userPendingorder); |
| | | continue; |
| | | } |
| | | |
| | | // 检查是否有配额 |
| | | if (!priceServices.isLimitUpBuy(stock.getStockCode())) { |
| | | continue; |
| | | } |
| | | |
| | | // 获取用户信息 |
| | | User user = this.userMapper.selectById(userPendingorder.getUserId()); |
| | | if (user == null) { |
| | | continue; |
| | | } |
| | | |
| | | // 执行买入逻辑(在 synchronized 块内) |
| | | synchronized (userPendingorder.getUserId()) { |
| | | // 再次检查挂单状态,防止并发处理 |
| | | UserPendingorder checkOrder = userPendingorderMapper.selectById(userPendingorder.getId()); |
| | | if (checkOrder == null || checkOrder.getStatus() != 0) { |
| | | // 挂单已被处理,跳过本次循环 |
| | | continue orderLoop; |
| | | } |
| | | |
| | | // 手续费率 |