| | |
| | | package com.yami.trading.api.controller; |
| | | |
| | | import cn.hutool.core.collection.CollectionUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.yami.trading.api.dto.CloseAction; |
| | | import com.yami.trading.api.dto.OpenAction; |
| | |
| | | import com.yami.trading.common.util.ThreadUtils; |
| | | import com.yami.trading.security.common.util.SecurityUtils; |
| | | import com.yami.trading.service.SessionTokenService; |
| | | import com.yami.trading.service.StrongLevelCalculationService; |
| | | import com.yami.trading.service.WalletService; |
| | | import com.yami.trading.service.contract.ContractApplyOrderService; |
| | | import com.yami.trading.service.contract.ContractLockService; |
| | |
| | | BigDecimal contractOpenLimitMax = new BigDecimal(sysparaService.find("contract_open_limit_max").getSvalue()); |
| | | data.put("contract_open_limit_max", contractOpenLimitMax); |
| | | |
| | | |
| | | return Result.succeed(data); |
| | | |
| | | } |
| | |
| | | */ |
| | | @RequestMapping(action + "open.action") |
| | | public Result<String> open(@Valid OpenAction openAction) throws IOException, InterruptedException { |
| | | String symbol = openAction.getSymbol(); |
| | | // Item bySymbol = itemService.findBySymbol(symbol); |
| | | // if(bySymbol == null){ |
| | | // throw new YamiShopBindException("当前币对不存在"); |
| | | // } |
| | | // boolean isOpen = MarketOpenChecker.isMarketOpenByItemCloseType(bySymbol.getOpenCloseType()); |
| | | // if(!isOpen){ |
| | | // throw new YamiShopBindException("当前已经休市"); |
| | | // } |
| | | |
| | | String partyId = SecurityUtils.getUser().getUserId(); |
| | | RLock rLock = redissonClient.getLock("contract_open_" + partyId); |
| | | boolean lockResult = rLock.tryLock(5, TimeUnit.SECONDS); |
| | | if (!lockResult) { |
| | | throw new YamiShopBindException("请稍后再试"); |
| | | } |
| | | |
| | | boolean lockAcquired = false; |
| | | double faceValue = 0.01;//面值 |
| | | double minAmount = 0.01;//最低张数 |
| | | try { |
| | | User user = userService.getById(partyId); |
| | | if (!user.isEnabled()) { |
| | | throw new YamiShopBindException("用户已锁定"); |
| | | // 尝试获取锁,最多等待5秒 |
| | | lockAcquired = rLock.tryLock(5, TimeUnit.SECONDS); |
| | | if (!lockAcquired) { |
| | | log.warn("无法获取锁: contract_open_{}", partyId); |
| | | throw new YamiShopBindException("Please try again later"); |
| | | } |
| | | //判断下单金额是否符合最低金额 最低下单张数:0.01 |
| | | //合约张数 张数=保证金*杠杆倍数/(面值*最新成交价) |
| | | double v = openAction.getAmount().doubleValue() * openAction.getLever_rate().doubleValue() / (faceValue * openAction.getPrice().doubleValue()); |
| | | BigDecimal amount = BigDecimal.valueOf(v).setScale(4, RoundingMode.DOWN); |
| | | if (amount.compareTo(new BigDecimal(faceValue)) < 0) { |
| | | double minimumAmount = minAmount * faceValue * openAction.getPrice().doubleValue() / openAction.getLever_rate().doubleValue(); |
| | | double roundedAmount = Math.ceil(minimumAmount * 10000) / 10000; |
| | | throw new YamiShopBindException("Minimum order amount: " + roundedAmount); |
| | | } |
| | | |
| | | Syspara syspara = sysparaService.find("stop_user_internet"); |
| | | String stopUserInternet = syspara.getSvalue(); |
| | | if(org.apache.commons.lang3.StringUtils.isNotEmpty(stopUserInternet)) { |
| | | String[] stopUsers = stopUserInternet.split(","); |
| | | // 校验当前用户订单状态 |
| | | checkContractOrderStatus(openAction, partyId); |
| | | |
| | | System.out.println("userName = " + user.getUserName()); |
| | | System.out.println("stopUserInternet = " + stopUserInternet); |
| | | // 校验用户是否被锁定 |
| | | checkUserStatus(partyId); |
| | | |
| | | if(Arrays.asList(stopUsers).contains(user.getUserName())){ |
| | | throw new YamiShopBindException("无网络"); |
| | | } |
| | | } |
| | | // 校验用户网络限制 |
| | | checkUserNetworkRestriction(partyId); |
| | | |
| | | ContractApplyOrder order = new ContractApplyOrder(); |
| | | order.setPartyId(partyId); |
| | | order.setSymbol(openAction.getSymbol()); |
| | | order.setDirection(openAction.getDirection()); |
| | | order.setOffset(ContractApplyOrder.OFFSET_OPEN); |
| | | order.setVolume(openAction.getAmount()); |
| | | order.setVolumeOpen(openAction.getAmount()); |
| | | order.setLeverRate(openAction.getLever_rate()); |
| | | order.setPrice(openAction.getPrice()); |
| | | order.setStopPriceProfit(openAction.getStop_price_profit()); |
| | | order.setStopPriceLoss(openAction.getStop_price_loss()); |
| | | order.setOrderPriceType(openAction.getPrice_type()); |
| | | order.setState(ContractApplyOrder.STATE_SUBMITTED); |
| | | this.contractApplyOrderService.saveCreate(order); |
| | | // 创建新的合约申请订单 |
| | | createContractApplyOrder(openAction, partyId); |
| | | |
| | | } catch (YamiShopBindException e) { |
| | | log.error("错误信息: {}", e.getMessage(), e); |
| | | throw e; // 重新抛出自定义异常 |
| | | } catch (Exception e) { |
| | | log.error("下单失败" , e); |
| | | return Result.failed(e.getMessage()); |
| | | |
| | | log.error("系统异常: {}", e.getMessage(), e); |
| | | throw new YamiShopBindException("Operation failed, please try again later"); |
| | | } finally { |
| | | rLock.unlock(); |
| | | // 确保释放锁 |
| | | if (lockAcquired && rLock.isHeldByCurrentThread()) { |
| | | rLock.unlock(); |
| | | } |
| | | } |
| | | |
| | | return Result.succeed(null,"ok"); |
| | | |
| | | |
| | | return Result.succeed(null, "ok"); |
| | | } |
| | | |
| | | // 校验合约订单状态 |
| | | private void checkContractOrderStatus(OpenAction openAction, String partyId) { |
| | | LambdaQueryWrapper<ContractOrder> wrapper = new LambdaQueryWrapper<>(); |
| | | wrapper.eq(ContractOrder::getPartyId, partyId); |
| | | wrapper.eq(ContractOrder::getState, "submitted"); |
| | | wrapper.eq(ContractOrder::getLocationType, openAction.getLocationType() == 0 ? 1 : 0); |
| | | |
| | | List<ContractOrder> list = contractOrderService.list(wrapper); |
| | | if (CollectionUtil.isNotEmpty(list)) { |
| | | String errorMessage = openAction.getLocationType() == 0 ? |
| | | "下单失败,当前持有全仓仓位,不支持逐仓下单!" : |
| | | "下单失败,当前持有逐仓仓位,不支持全仓下单!"; |
| | | throw new YamiShopBindException(errorMessage); |
| | | } |
| | | } |
| | | |
| | | // 校验用户状态 |
| | | private void checkUserStatus(String partyId) { |
| | | User user = userService.getById(partyId); |
| | | if (!user.isEnabled()) { |
| | | throw new YamiShopBindException("User is locked"); |
| | | } |
| | | } |
| | | |
| | | // 校验用户网络限制 |
| | | private void checkUserNetworkRestriction(String partyId) { |
| | | Syspara syspara = sysparaService.find("stop_user_internet"); |
| | | String stopUserInternet = syspara.getSvalue(); |
| | | |
| | | if (StringUtils.isNotEmpty(stopUserInternet)) { |
| | | String[] stopUsers = stopUserInternet.split(","); |
| | | User user = userService.getById(partyId); |
| | | if (Arrays.asList(stopUsers).contains(user.getUserName())) { |
| | | throw new YamiShopBindException("No network connection"); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 创建合约申请订单 |
| | | private void createContractApplyOrder(OpenAction openAction, String partyId) { |
| | | ContractApplyOrder order = new ContractApplyOrder(); |
| | | order.setPartyId(partyId); |
| | | order.setSymbol(openAction.getSymbol()); |
| | | order.setDirection(openAction.getDirection()); |
| | | order.setOffset(ContractApplyOrder.OFFSET_OPEN); |
| | | // order.setVolume(openAction.getAmount()); |
| | | // order.setVolumeOpen(openAction.getAmount()); |
| | | order.setLeverRate(openAction.getLever_rate()); |
| | | order.setPrice(openAction.getPrice()); |
| | | order.setStopPriceProfit(openAction.getStop_price_profit()); |
| | | order.setStopPriceLoss(openAction.getStop_price_loss()); |
| | | order.setOrderPriceType(openAction.getPrice_type()); |
| | | order.setState(ContractApplyOrder.STATE_SUBMITTED); |
| | | order.setMoney(openAction.getAmount()); |
| | | order.setLocationType(openAction.getLocationType()); |
| | | contractApplyOrderService.saveCreate(order); |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | |
| | | RLock rLock = redissonClient.getLock("contract_close_" + partyId); |
| | | boolean lockResult = rLock.tryLock(5, TimeUnit.SECONDS); |
| | | if (!lockResult) { |
| | | throw new YamiShopBindException("请稍后再试"); |
| | | throw new YamiShopBindException("Please try again later"); |
| | | } |
| | | try { |
| | | User user = userService.getById(partyId); |
| | | if (!user.isEnabled()) { |
| | | throw new YamiShopBindException("用户已锁定"); |
| | | throw new YamiShopBindException("User is locked"); |
| | | } |
| | | |
| | | Syspara syspara = sysparaService.find("stop_user_internet"); |
| | |
| | | System.out.println("stopUserInternet = " + stopUserInternet); |
| | | |
| | | if(Arrays.asList(stopUsers).contains(user.getUserName())){ |
| | | throw new YamiShopBindException("无网络"); |
| | | throw new YamiShopBindException("No network connection"); |
| | | } |
| | | } |
| | | |
| | |
| | | order.setPartyId(partyId); |
| | | order.setSymbol(closeAction.getSymbol()); |
| | | order.setDirection(closeAction.getDirection()); |
| | | order.setOffset(ContractApplyOrder.OFFSET_OPEN); |
| | | order.setOffset(ContractApplyOrder.OFFSET_CLOSE); |
| | | order.setVolume(closeAction.getAmount()); |
| | | order.setVolumeOpen(closeAction.getAmount()); |
| | | order.setPrice(closeAction.getPrice()); |
| | |
| | | |
| | | ContractApplyOrder order = this.contractApplyOrderService.findByOrderNo(order_no); |
| | | if (order == null) { |
| | | throw new YamiShopBindException("委托单不存在"); |
| | | throw new YamiShopBindException("Order does not exist"); |
| | | } |
| | | Map<String, Object> map = new HashMap<String, Object>(); |
| | | map.put("order_no", order.getOrderNo()); |
| | |
| | | |
| | | } catch (Exception e) { |
| | | log.error("执行撤单异常", e); |
| | | throw new YamiShopBindException("执行撤单异常"); |
| | | throw new YamiShopBindException("Failed to cancel order"); |
| | | } |
| | | |
| | | return Result.succeed(null,"success"); |
| | |
| | | |
| | | } catch (Exception e) { |
| | | log.error("执行撤单异常", e); |
| | | throw new YamiShopBindException("执行撤单异常"); |
| | | throw new YamiShopBindException("Failed to cancel order"); |
| | | } |
| | | |
| | | return Result.succeed(null,"success"); |
| | |
| | | Page<ContractApplyOrder> result = contractApplyOrderService.findList(page, SecurityUtils.getUser().getUserId(), type, symbolType); |
| | | List<ContractApplyOrder> datas = result.getRecords(); |
| | | if (!StringUtils.isInteger(page_no)) { |
| | | throw new YamiShopBindException("页码不是整数"); |
| | | throw new YamiShopBindException("Page number must be an integer"); |
| | | } |
| | | if (Integer.valueOf(page_no).intValue() <= 0) { |
| | | throw new YamiShopBindException("页码不能小于等于0"); |
| | | throw new YamiShopBindException("Page number must be greater than 0"); |
| | | } |
| | | Long count = 0L; |
| | | |