| | |
| | | import com.github.pagehelper.PageInfo; |
| | | import com.google.common.collect.Lists; |
| | | import com.nq.common.ServerResponse; |
| | | import com.nq.utils.DateTimeUtil; |
| | | import com.nq.utils.timeutil.DateTimeUtil; |
| | | import com.nq.utils.KeyUtils; |
| | | import com.nq.utils.stock.BuyAndSellUtils; |
| | | import com.nq.vo.agent.AgentIncomeVO; |
| | |
| | | import java.sql.Timestamp; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | import javax.annotation.Resource; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | |
| | | import org.apache.commons.lang3.StringUtils; |
| | |
| | | public class UserFuturesPositionServiceImpl implements IUserFuturesPositionService { |
| | | private static final Logger log = LoggerFactory.getLogger(UserFuturesPositionServiceImpl.class); |
| | | |
| | | @Autowired |
| | | @Resource |
| | | UserFuturesPositionMapper userFuturesPositionMapper; |
| | | |
| | | @Autowired |
| | |
| | | @Autowired |
| | | IAgentUserService iAgentUserService; |
| | | |
| | | @Autowired |
| | | @Resource |
| | | AgentUserMapper agentUserMapper; |
| | | |
| | | @Autowired |
| | | IStockCoinService iStockCoinService; |
| | | @Autowired |
| | | @Resource |
| | | UserMapper userMapper; |
| | | @Autowired |
| | | @Resource |
| | | UserCashDetailMapper userCashDetailMapper; |
| | | @Autowired |
| | | ISiteFuturesSettingService iSiteFuturesSettingService; |
| | | @Autowired |
| | | @Resource |
| | | StockFuturesMapper stockFuturesMapper; |
| | | @Autowired |
| | | ISiteProductService iSiteProductService; |
| | | |
| | | @Transactional |
| | | public ServerResponse buyFutures(Integer futuresId, Integer buyNum, Integer buyType, Integer lever, HttpServletRequest request) throws Exception { |
| | | if (futuresId == null || buyNum == null || buyType == null) { |
| | | return ServerResponse.createByErrorMsg("参数不能为空"); |
| | | } |
| | | /*实名认证开关开启*/ |
| | | SiteProduct siteProduct = iSiteProductService.getProductSetting(); |
| | | User user = this.iUserService.getCurrentRefreshUser(request); |
| | | if (siteProduct.getRealNameDisplay() && (StringUtils.isBlank(user.getRealName()) || StringUtils.isBlank(user.getIdCard()))) { |
| | | return ServerResponse.createByErrorMsg("下单失败,请先实名认证"); |
| | | } |
| | | |
| | | if(siteProduct.getHolidayDisplay()){ |
| | | return ServerResponse.createByErrorMsg("周末或节假日不能交易!"); |
| | | } |
| | | |
| | | if (siteProduct.getRealNameDisplay() && user.getIsLock().intValue() == 1) { |
| | | return ServerResponse.createByErrorMsg("下单失败,账户已被锁定"); |
| | | } |
| | | |
| | | StockFutures stockFutures = this.iStockFuturesService.selectFuturesById(futuresId); |
| | | if (stockFutures == null) { |
| | | return ServerResponse.createByErrorMsg("产品不存在"); |
| | | } |
| | | if (1 != stockFutures.getTransState().intValue()) { |
| | | return ServerResponse.createByErrorMsg("该产品不能交易"); |
| | | } |
| | | if (buyNum.intValue() < stockFutures.getMinNum().intValue()) { |
| | | return ServerResponse.createByErrorMsg("最低不能低于" + stockFutures.getMinNum() + "手"); |
| | | } |
| | | if (buyNum.intValue() > stockFutures.getMaxNum().intValue()) { |
| | | return ServerResponse.createByErrorMsg("最多不能高于" + stockFutures.getMaxNum() + "手"); |
| | | } |
| | | log.info("用户 {} 下单, 期货产品 = {} ,数量 = {} 手 , 方向 = {} , 杠杆倍数 = {}", new Object[]{user |
| | | .getId(), stockFutures.getFuturesName(), buyNum, buyType, lever}); |
| | | |
| | | |
| | | String am_begin = stockFutures.getTransAmBegin(); |
| | | String am_end = stockFutures.getTransAmEnd(); |
| | | String pm_begin = stockFutures.getTransPmBegin(); |
| | | String pm_end = stockFutures.getTransPmEnd(); |
| | | String pm_begin2 = stockFutures.getTransPmBegin2(); |
| | | String pm_end2 = stockFutures.getTransPmEnd2(); |
| | | boolean am_flag = BuyAndSellUtils.isTransTime(am_begin, am_end); |
| | | boolean pm_flag = BuyAndSellUtils.isTransTime(pm_begin, pm_end); |
| | | boolean pm_flag2 = BuyAndSellUtils.isTransTime(pm_begin2, pm_end2); |
| | | log.info("futures 是否在上午交易时间 = {} 是否在下午交易时间 = {}是否在下午交易时间2 = {}", Boolean.valueOf(am_flag), Boolean.valueOf(pm_flag), Boolean.valueOf(pm_flag2)); |
| | | if (!am_flag && !pm_flag && !pm_flag2) { |
| | | return ServerResponse.createByErrorMsg("下单失败,不在交易时段内"); |
| | | } |
| | | |
| | | |
| | | SiteFuturesSetting siteFuturesSetting = this.iSiteFuturesSettingService.getSetting(); |
| | | if (siteFuturesSetting == null) { |
| | | log.error("下单出错,网站设置表不存在"); |
| | | return ServerResponse.createByErrorMsg("下单失败,系统设置错误"); |
| | | } |
| | | |
| | | List dbPosition = findPositionByFuturesCodeAndTimes(siteFuturesSetting.getBuySameTimes().intValue(), stockFutures |
| | | .getFuturesCode(), user.getId()); |
| | | if (dbPosition.size() >= siteFuturesSetting.getBuySameNums().intValue()) { |
| | | return ServerResponse.createByErrorMsg("频繁交易," + siteFuturesSetting.getBuySameTimes() + "分钟内同一产品持仓不得超过" + siteFuturesSetting |
| | | .getBuySameNums() + "条"); |
| | | } |
| | | |
| | | Integer transNum = findPositionNumByTimes(siteFuturesSetting.getBuyNumTimes().intValue(), user.getId()); |
| | | if (transNum.intValue() >= siteFuturesSetting.getBuyNumLots().intValue()) { |
| | | return ServerResponse.createByErrorMsg("频繁交易," + siteFuturesSetting.getBuyNumTimes() + "分钟内不能超过" + siteFuturesSetting |
| | | .getBuyNumLots() + "手"); |
| | | } |
| | | |
| | | |
| | | // 保证金= 期货保证金*数量/杠杆倍数 |
| | | BigDecimal all_deposit_amt = (new BigDecimal(stockFutures.getDepositAmt().intValue())).multiply(new BigDecimal(buyNum.intValue())).divide(new BigDecimal(lever)).setScale(4,2); |
| | | |
| | | |
| | | BigDecimal all_order_fee = (new BigDecimal(stockFutures.getTransFee().intValue())).multiply(new BigDecimal(buyNum.intValue())); |
| | | |
| | | |
| | | ServerResponse exchangeRateResponse = this.iStockFuturesService.getExchangeRate(stockFutures.getCoinCode()); |
| | | if (!exchangeRateResponse.isSuccess()) { |
| | | return ServerResponse.createByErrorMsg(exchangeRateResponse.getMsg()); |
| | | } |
| | | BigDecimal exchangeRate = (BigDecimal) exchangeRateResponse.getData(); |
| | | log.info("期货产品 {} , 基币 {} , 汇率模版采用 {} ", new Object[]{stockFutures.getFuturesName(), stockFutures |
| | | .getCoinCode(), exchangeRate}); |
| | | |
| | | BigDecimal all_usd_amt = all_deposit_amt; |
| | | log.info("需要支付的总资金(保证金) = {} 未计算汇率", all_usd_amt); |
| | | |
| | | all_usd_amt = all_usd_amt.multiply(exchangeRate); |
| | | log.info("计算汇率后 人民币 = {} ", all_usd_amt); |
| | | |
| | | |
| | | if (user.getEnableFutAmt().compareTo(all_usd_amt) == -1) { |
| | | return ServerResponse.createByErrorMsg("账户资金不足"); |
| | | } |
| | | if (user.getUserAmt().compareTo(new BigDecimal("0")) == -1) { |
| | | return ServerResponse.createByErrorMsg("失败,融资总资金小于0"); |
| | | } |
| | | if (user.getUserIndexAmt().compareTo(new BigDecimal("0")) == -1) { |
| | | return ServerResponse.createByErrorMsg("失败,指数总资金小于0"); |
| | | } |
| | | |
| | | |
| | | BigDecimal max_buy_amt = user.getEnableFutAmt().multiply(siteFuturesSetting.getBuyMaxPercent()); |
| | | if (max_buy_amt.compareTo(all_usd_amt) == -1) { |
| | | return ServerResponse.createByErrorMsg("不能超过最大购买比例"); |
| | | } |
| | | |
| | | |
| | | FuturesVO futuresVO = this.iStockFuturesService.querySingleMarket(stockFutures.getFuturesGid()); |
| | | log.info("期货下单 {} , 价格 = {}", futuresVO.getName(), futuresVO.getNowPrice()); |
| | | |
| | | |
| | | BigDecimal reckon_enable = user.getEnableFutAmt().subtract(all_usd_amt); |
| | | user.setEnableFutAmt(reckon_enable); |
| | | int updateUserCount = this.userMapper.updateByPrimaryKeySelective(user); |
| | | if (updateUserCount > 0) { |
| | | log.info("【用户交易 期货 下单】修改用户金额成功"); |
| | | } else { |
| | | log.error("【用户交易 期货 下单】修改用户金额出错"); |
| | | throw new Exception("【用户交易 期货 下单】修改用户金额出错"); |
| | | } |
| | | |
| | | |
| | | UserFuturesPosition userFuturesPosition = new UserFuturesPosition(); |
| | | userFuturesPosition.setPositionType(user.getAccountType()); |
| | | userFuturesPosition.setPositionSn(KeyUtils.getUniqueKey()); |
| | | userFuturesPosition.setUserId(user.getId()); |
| | | userFuturesPosition.setRealName(user.getRealName()); |
| | | userFuturesPosition.setAgentId(user.getAgentId()); |
| | | userFuturesPosition.setFuturesName(stockFutures.getFuturesName()); |
| | | userFuturesPosition.setFuturesCode(stockFutures.getFuturesCode()); |
| | | userFuturesPosition.setFuturesGid(stockFutures.getFuturesGid()); |
| | | userFuturesPosition.setBuyOrderTime(new Date()); |
| | | userFuturesPosition.setBuyOrderPrice(new BigDecimal(futuresVO.getNowPrice())); |
| | | userFuturesPosition.setOrderDirection((buyType.intValue() == 0) ? "买涨" : "买跌"); |
| | | |
| | | userFuturesPosition.setOrderNum(buyNum); |
| | | userFuturesPosition.setFuturesStandard(stockFutures.getFuturesStandard()); |
| | | userFuturesPosition.setFuturesUnit(stockFutures.getFuturesUnit()); |
| | | |
| | | userFuturesPosition.setAllDepositAmt(all_usd_amt); |
| | | userFuturesPosition.setOrderFee(all_order_fee); |
| | | userFuturesPosition.setIsLock(Integer.valueOf(0)); |
| | | userFuturesPosition.setProfitAndLose(new BigDecimal("0")); |
| | | userFuturesPosition.setAllProfitAndLose(new BigDecimal("0")); |
| | | userFuturesPosition.setBuyRate(exchangeRate); |
| | | |
| | | userFuturesPosition.setCoinCode(stockFutures.getCoinCode()); |
| | | userFuturesPosition.setOrderLever(lever); |
| | | |
| | | |
| | | int insertPositionCount = this.userFuturesPositionMapper.insert(userFuturesPosition); |
| | | if (insertPositionCount > 0) { |
| | | log.info("【用户交易 期货 下单】保存持仓记录成功"); |
| | | } else { |
| | | log.error("用户交易 期货 下单】保存持仓记录出错"); |
| | | throw new Exception("用户交易 期货 下单】保存持仓记录出错"); |
| | | } |
| | | |
| | | return ServerResponse.createBySuccess("Order successful"); |
| | | } |
| | |
| | | |
| | | |
| | | public ServerResponse sellFutures(String positionSn, int doType) throws Exception { |
| | | log.info("【 用户交易平仓 期货 】 positionSn = {} , dotype = {}", positionSn, Integer.valueOf(doType)); |
| | | |
| | | |
| | | UserFuturesPosition userFuturesPosition = this.userFuturesPositionMapper.selectPositionBySn(positionSn); |
| | | if (userFuturesPosition == null) { |
| | | return ServerResponse.createByErrorMsg("操作失败,找不到订单"); |
| | | } |
| | | |
| | | |
| | | StockFutures stockFutures = this.iStockFuturesService.selectFuturesByCode(userFuturesPosition.getFuturesCode()); |
| | | if (stockFutures == null) { |
| | | return ServerResponse.createByErrorMsg("操作失败,产品不存在或已被删除"); |
| | | } |
| | | |
| | | |
| | | if (doType != 0) { |
| | | String am_begin = stockFutures.getTransAmBegin(); |
| | | String am_end = stockFutures.getTransAmEnd(); |
| | | String pm_begin = stockFutures.getTransPmBegin(); |
| | | String pm_end = stockFutures.getTransPmEnd(); |
| | | String pm_begin2 = stockFutures.getTransPmBegin2(); |
| | | String pm_end2 = stockFutures.getTransPmEnd2(); |
| | | boolean am_flag = BuyAndSellUtils.isTransTime(am_begin, am_end); |
| | | boolean pm_flag = BuyAndSellUtils.isTransTime(pm_begin, pm_end); |
| | | boolean pm_flag2 = BuyAndSellUtils.isTransTime(pm_begin2, pm_end2); |
| | | log.info("【 期货 】是否在上午交易时间 = {} 是否在下午交易时间 = {}", Boolean.valueOf(am_flag), Boolean.valueOf(pm_flag)); |
| | | if (!am_flag && !pm_flag && !pm_flag2) { |
| | | return ServerResponse.createByErrorMsg("操作失败,不在交易时段内"); |
| | | } |
| | | } |
| | | |
| | | |
| | | User user = this.userMapper.selectByPrimaryKey(userFuturesPosition.getUserId()); |
| | | /*实名认证开关开启*/ |
| | | SiteProduct siteProduct = iSiteProductService.getProductSetting(); |
| | | if (siteProduct.getRealNameDisplay() && user.getIsLock().intValue() == 1) { |
| | | return ServerResponse.createByErrorMsg("操作失败,用户已被锁定"); |
| | | } |
| | | if(siteProduct.getHolidayDisplay()){ |
| | | return ServerResponse.createByErrorMsg("周末或节假日不能交易!"); |
| | | } |
| | | |
| | | if (userFuturesPosition.getSellOrderPrice() != null) { |
| | | return ServerResponse.createByErrorMsg("操作失败,此订单已平仓"); |
| | | } |
| | | |
| | | if (1 == userFuturesPosition.getIsLock().intValue()) { |
| | | return ServerResponse.createByErrorMsg("平仓失败 " + userFuturesPosition.getLockMsg()); |
| | | } |
| | | |
| | | |
| | | FuturesVO futuresVO = this.iStockFuturesService.querySingleMarket(stockFutures.getFuturesGid()); |
| | | log.info("平仓 期货订单 {} ,平仓价格为 {}", userFuturesPosition.getId(), futuresVO.getNowPrice()); |
| | | |
| | | |
| | | userFuturesPosition.setSellOrderPrice(new BigDecimal(futuresVO.getNowPrice())); |
| | | userFuturesPosition.setSellOrderTime(new Date()); |
| | | |
| | | BigDecimal point_sub = userFuturesPosition.getSellOrderPrice().setScale(2,4).subtract(userFuturesPosition.getBuyOrderPrice().setScale(2,4)); |
| | | |
| | | //每手浮动价格 |
| | | BigDecimal eachPoint = new BigDecimal("1"); |
| | | if(stockFutures!=null && stockFutures.getEachPoint() != null){ |
| | | eachPoint = stockFutures.getEachPoint(); |
| | | } |
| | | //BigDecimal profit_and_lose = point_sub.multiply(new BigDecimal(userFuturesPosition.getFuturesStandard().intValue())).multiply(new BigDecimal(userFuturesPosition.getOrderNum().intValue())); |
| | | BigDecimal profit_and_lose = point_sub.multiply(eachPoint).multiply(new BigDecimal(userFuturesPosition.getOrderNum().intValue())); |
| | | if ("买跌".equals(userFuturesPosition.getOrderDirection())) { |
| | | profit_and_lose = profit_and_lose.negate(); |
| | | } |
| | | BigDecimal all_profit = profit_and_lose.subtract(userFuturesPosition.getOrderFee()); |
| | | |
| | | |
| | | ServerResponse exchangeRateResponse = this.iStockFuturesService.getExchangeRate(stockFutures.getCoinCode()); |
| | | if (!exchangeRateResponse.isSuccess()) { |
| | | return ServerResponse.createByErrorMsg(exchangeRateResponse.getMsg()); |
| | | } |
| | | BigDecimal exchangeRate = (BigDecimal) exchangeRateResponse.getData(); |
| | | exchangeRate = exchangeRate.setScale(2, 4); |
| | | log.info("【平仓】期货产品 {} , 基币 {} , 汇率模版采用 {} ", new Object[]{stockFutures.getFuturesName(), stockFutures |
| | | .getCoinCode(), exchangeRate}); |
| | | |
| | | userFuturesPosition.setSellRate(exchangeRate); |
| | | |
| | | |
| | | profit_and_lose = profit_and_lose.multiply(exchangeRate); |
| | | userFuturesPosition.setProfitAndLose(profit_and_lose); |
| | | log.info("【平仓】USD总盈亏 {} ", all_profit); |
| | | all_profit = all_profit.multiply(exchangeRate); |
| | | userFuturesPosition.setAllProfitAndLose(all_profit); |
| | | |
| | | |
| | | int updateFuturesPositionCount = this.userFuturesPositionMapper.updateByPrimaryKeySelective(userFuturesPosition); |
| | | if (updateFuturesPositionCount > 0) { |
| | | log.info("【用户平仓 期货 】修改浮动盈亏记录成功"); |
| | | } else { |
| | | log.error("【用户平仓 期货 】修改浮动盈亏记录出错"); |
| | | throw new Exception("用户平仓 期货 】修改浮动盈亏记录出错"); |
| | | } |
| | | |
| | | |
| | | BigDecimal before_user_amt = user.getUserFutAmt(); |
| | | BigDecimal before_enable_amt = user.getEnableFutAmt(); |
| | | log.info("用户平仓之前 的 总资金 = {} , 可用资金 = {}", before_user_amt, before_enable_amt); |
| | | |
| | | BigDecimal user_futures_amt = before_user_amt.add(all_profit); |
| | | |
| | | BigDecimal enable_futures_amt = before_enable_amt.add(all_profit).add(userFuturesPosition.getAllDepositAmt()); |
| | | |
| | | log.info("用户平仓后的总资金 = {} , 可用资金 = {}", user_futures_amt, enable_futures_amt); |
| | | user.setUserFutAmt(user_futures_amt); |
| | | user.setEnableFutAmt(enable_futures_amt); |
| | | |
| | | int updateUserCount = this.userMapper.updateByPrimaryKeySelective(user); |
| | | if (updateUserCount > 0) { |
| | | log.info("【用户平仓 期货 】修改用户金额成功"); |
| | | } else { |
| | | log.error("【用户平仓 期货 】修改用户金额出错"); |
| | | throw new Exception("【用户平仓 期货 】修改用户金额出错"); |
| | | } |
| | | |
| | | |
| | | UserCashDetail ucd = new UserCashDetail(); |
| | | ucd.setPositionId(userFuturesPosition.getId()); |
| | | ucd.setAgentId(user.getAgentId()); |
| | | ucd.setAgentName(user.getAgentName()); |
| | | ucd.setUserId(user.getId()); |
| | | ucd.setUserName(user.getRealName()); |
| | | ucd.setDeType("期货盈亏"); |
| | | ucd.setDeAmt(all_profit); |
| | | String deSummary = "卖出期货," + userFuturesPosition.getFuturesName() + "/" + userFuturesPosition.getFuturesCode() + ",总盈亏:" + all_profit; |
| | | ucd.setDeSummary(deSummary); |
| | | log.info("卖出期货资金明细:{}", deSummary); |
| | | |
| | | |
| | | ucd.setAddTime(new Date()); |
| | | ucd.setIsRead(Integer.valueOf(0)); |
| | | |
| | | int insertSxfCount = this.userCashDetailMapper.insert(ucd); |
| | | if (insertSxfCount > 0) { |
| | | log.info("【用户平仓 期货 】保存明细记录成功"); |
| | | } else { |
| | | log.error("【用户平仓 期货 】保存明细记录出错"); |
| | | throw new Exception("【用户平仓 期货 】保存明细记录出错"); |
| | | } |
| | | |
| | | return ServerResponse.createBySuccessMsg("Closed position successfully!"); |
| | | } |
| | | |