| | |
| | | * @param operaName |
| | | * @return |
| | | */ |
| | | public String saveOrderManualProfitPercent(String orderNo, Double manualProfitPercent, String profitLoss, String operaName) { |
| | | if (manualProfitPercent == null) { |
| | | return "盈亏百分比不能为空"; |
| | | } |
| | | double absPercent = Math.abs(manualProfitPercent); |
| | | if (absPercent <= 0) { |
| | | return "盈亏百分比必须大于0"; |
| | | } |
| | | double signedPercent; |
| | | String resolvedProfitLoss; |
| | | if (StrUtil.isNotBlank(profitLoss)) { |
| | | resolvedProfitLoss = profitLoss.trim().toLowerCase(); |
| | | if ("loss".equals(resolvedProfitLoss)) { |
| | | signedPercent = -absPercent; |
| | | resolvedProfitLoss = "loss"; |
| | | } else if ("profit".equals(resolvedProfitLoss)) { |
| | | signedPercent = absPercent; |
| | | resolvedProfitLoss = "profit"; |
| | | } else { |
| | | return "场控方向无效"; |
| | | } |
| | | } else { |
| | | signedPercent = manualProfitPercent; |
| | | resolvedProfitLoss = signedPercent >= 0 ? "profit" : "loss"; |
| | | } |
| | | String message = ""; |
| | | boolean lock = false; |
| | | while (true) { |
| | | try { |
| | | if (!FuturesLock.add(orderNo)) { |
| | | continue; |
| | | } |
| | | lock = true; |
| | | FuturesOrder futuresOrder = (FuturesOrder) RedisUtil.get(FuturesRedisKeys.FUTURES_SUBMITTED_ORDERNO + orderNo); |
| | | if (futuresOrder == null) { |
| | | futuresOrder = cache.get(orderNo); |
| | | } |
| | | if (futuresOrder == null || FuturesOrder.STATE_CREATED.equals(futuresOrder.getState())) { |
| | | message = "订单已结算或不存在"; |
| | | break; |
| | | } |
| | | Double oldPercent = futuresOrder.getManualProfitPercent(); |
| | | String oldProfitLoss = futuresOrder.getProfitLoss(); |
| | | futuresOrder.setProfitLoss(resolvedProfitLoss); |
| | | futuresOrder.setManualProfitPercent(signedPercent); |
| | | applyManualProfitPercentToOrder(futuresOrder); |
| | | Double close = futuresOrder.getCloseAvgPrice(); |
| | | if (close == null) { |
| | | close = futuresOrder.getTradeAvgPrice(); |
| | | } |
| | | refreshCache(futuresOrder, close); |
| | | RedisUtil.set(FuturesRedisKeys.FUTURES_SUBMITTED_ORDERNO + futuresOrder.getOrderNo(), futuresOrder); |
| | | cache.put(futuresOrder.getOrderNo(), futuresOrder); |
| | | updateById(futuresOrder); |
| | | |
| | | User party = userService.getById(futuresOrder.getPartyId()); |
| | | Log log = new Log(); |
| | | log.setCategory(Constants.LOG_CATEGORY_OPERATION); |
| | | log.setOperator(operaName); |
| | | log.setUsername(party.getUserName()); |
| | | log.setUserId(party.getUserId()); |
| | | log.setCreateTime(new Date()); |
| | | log.setLog("设定交割订单场控与盈亏比例。订单号[" + futuresOrder.getOrderNo() + "],场控[" |
| | | + Constants.PROFIT_LOSS_TYPE.get(oldProfitLoss) + "→" |
| | | + Constants.PROFIT_LOSS_TYPE.get(resolvedProfitLoss) + "],比例[" |
| | | + oldPercent + "→" + signedPercent + "%]."); |
| | | this.logService.save(log); |
| | | ThreadUtils.sleep(100); |
| | | } catch (Throwable e) { |
| | | log.error("error:", e); |
| | | message = "修改错误"; |
| | | } finally { |
| | | if (lock) { |
| | | FuturesLock.remove(orderNo); |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | return message; |
| | | } |
| | | |
| | | public String saveOrderPorfitOrLoss(String orderNo, String porfitOrLoss, String operaName) { |
| | | String message = ""; |
| | | boolean lock = false; |
| | |
| | | Map<String, Double> futuresAssetsOld = this.walletService.getMoneyFuturesByOrder(futuresOrder); |
| | | |
| | | String oldProfitLoss = futuresOrder.getProfitLoss(); |
| | | futuresOrder.setManualProfitPercent(null); |
| | | futuresOrder.setProfitLoss(porfitOrLoss); |
| | | |
| | | RedisUtil.set(FuturesRedisKeys.FUTURES_SUBMITTED_ORDERNO + futuresOrder.getOrderNo(), futuresOrder); |
| | |
| | | realtime = realtime_list.get(0); |
| | | } |
| | | if (null == realtime) { |
| | | throw new BusinessException(1, "请稍后再试"); |
| | | throw new BusinessException(1, "行情获取失败,请稍后再试"); |
| | | } |
| | | |
| | | Double volume = futuresOrder.getVolume(); |
| | |
| | | order.setRemainTime(fomatTime(remain_time)); |
| | | order.setCloseAvgPrice(close); |
| | | |
| | | double futures_loss_part = Double.valueOf(this.sysparaService.find("futures_loss_part").getSvalue()); |
| | | |
| | | double closeAvgPrice = order.getCloseAvgPrice().doubleValue(); |
| | | double tradeAvgPrice = order.getTradeAvgPrice().doubleValue(); |
| | | if (FuturesOrder.DIRECTION_BUY.equals(order.getDirection())) { |
| | | /* |
| | | * 0 买涨 |
| | | */ |
| | | if (closeAvgPrice >= tradeAvgPrice) { |
| | | DecimalFormat df = new DecimalFormat("#.##"); |
| | | order.setProfit(Double.valueOf(df.format(Arith.mul(order.getVolume(), order.getProfitRatio())))); |
| | | } |
| | | |
| | | if (closeAvgPrice <= tradeAvgPrice) { |
| | | if (futures_loss_part == 2) { |
| | | DecimalFormat df = new DecimalFormat("#.##"); |
| | | order.setProfit(Arith.sub(0, Double.valueOf(df.format(Arith.mul(order.getVolume(), order.getProfitRatio()))))); |
| | | } else { |
| | | order.setProfit(Arith.sub(0, order.getVolume())); |
| | | } |
| | | } |
| | | if (order.getManualProfitPercent() != null) { |
| | | applyManualProfitPercentToOrder(order); |
| | | } else { |
| | | /* |
| | | * 1 买跌 |
| | | */ |
| | | if (closeAvgPrice <= tradeAvgPrice) { |
| | | DecimalFormat df = new DecimalFormat("#.##"); |
| | | order.setProfit(Double.valueOf(df.format(Arith.mul(order.getVolume(), order.getProfitRatio())))); |
| | | } |
| | | if (closeAvgPrice >= tradeAvgPrice) { |
| | | if (futures_loss_part == 2) { |
| | | double futures_loss_part = Double.valueOf(this.sysparaService.find("futures_loss_part").getSvalue()); |
| | | |
| | | double closeAvgPrice = order.getCloseAvgPrice().doubleValue(); |
| | | double tradeAvgPrice = order.getTradeAvgPrice().doubleValue(); |
| | | if (FuturesOrder.DIRECTION_BUY.equals(order.getDirection())) { |
| | | /* |
| | | * 0 买涨 |
| | | */ |
| | | if (closeAvgPrice >= tradeAvgPrice) { |
| | | DecimalFormat df = new DecimalFormat("#.##"); |
| | | order.setProfit(Arith.sub(0, Double.valueOf(df.format(Arith.mul(order.getVolume(), order.getProfitRatio()))))); |
| | | } else { |
| | | order.setProfit(Arith.sub(0, order.getVolume())); |
| | | order.setProfit(Double.valueOf(df.format(Arith.mul(order.getVolume(), order.getProfitRatio())))); |
| | | } |
| | | |
| | | if (closeAvgPrice <= tradeAvgPrice) { |
| | | if (futures_loss_part == 2) { |
| | | DecimalFormat df = new DecimalFormat("#.##"); |
| | | order.setProfit(Arith.sub(0, Double.valueOf(df.format(Arith.mul(order.getVolume(), order.getProfitRatio()))))); |
| | | } else { |
| | | order.setProfit(Arith.sub(0, order.getVolume())); |
| | | } |
| | | } |
| | | } else { |
| | | /* |
| | | * 1 买跌 |
| | | */ |
| | | if (closeAvgPrice <= tradeAvgPrice) { |
| | | DecimalFormat df = new DecimalFormat("#.##"); |
| | | order.setProfit(Double.valueOf(df.format(Arith.mul(order.getVolume(), order.getProfitRatio())))); |
| | | } |
| | | if (closeAvgPrice >= tradeAvgPrice) { |
| | | if (futures_loss_part == 2) { |
| | | DecimalFormat df = new DecimalFormat("#.##"); |
| | | order.setProfit(Arith.sub(0, Double.valueOf(df.format(Arith.mul(order.getVolume(), order.getProfitRatio()))))); |
| | | } else { |
| | | order.setProfit(Arith.sub(0, order.getVolume())); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | order.setCloseTime(System.currentTimeMillis() / 1000); |
| | | order.setState(FuturesOrder.STATE_CREATED); |
| | | |
| | | if (order.getManualProfitPercent() != null) { |
| | | settleByManualProfitPercent(order); |
| | | return; |
| | | } |
| | | |
| | | String ProfitLoss = null; |
| | | /** |
| | | * 计算盈亏状态 |
| | |
| | | "futures24Profit:{}, futures24Amount:{}, futures_ratio:{}, futures_most_prfit_level:{}", |
| | | order.getOrderNo(), futures24Profit, futures24Amount, futures_ratio, futures_most_prfit_level); |
| | | |
| | | ProfitLoss = "loss"; |
| | | |
| | | // ProfitAndLossConfig_on = 1; |
| | | } |
| | | } |
| | | |
| | | }else{ |
| | | ProfitLoss = "loss"; |
| | | } |
| | | |
| | | |
| | |
| | | tipService.deleteTip(order.getUuid()); |
| | | } |
| | | |
| | | private void settleByManualProfitPercent(FuturesOrder order) { |
| | | applyManualProfitPercentToOrder(order); |
| | | if (order.getProfit() >= 0) { |
| | | order.setProfitLoss("profit"); |
| | | } else { |
| | | order.setProfitLoss("loss"); |
| | | } |
| | | double profit = order.getProfit(); |
| | | logger.warn("---> FuturesOrderService.settleByManualProfitPercent 订单:{} 使用手动盈亏百分比:{}%, profit:{}", |
| | | order.getOrderNo(), order.getManualProfitPercent(), profit); |
| | | |
| | | if (profit > 0) { |
| | | BigDecimal amount = BigDecimal.valueOf(order.getProfit()).add(BigDecimal.valueOf(order.getVolume())); |
| | | walletService.updateMoney(order.getSymbol(), order.getPartyId(), amount, BigDecimal.ZERO, |
| | | Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET, Constants.DELIVERY_MONEYLOG_CONTENT_CONTRACT_CLOSE, |
| | | "交割合约盈利(手动盈亏%),订单号[" + order.getOrderNo() + "]"); |
| | | String future_profit_bonus_parameters = sysparaService.find("future_profit_bonus_parameters").getSvalue(); |
| | | if (StringUtils.isNotEmpty(future_profit_bonus_parameters)) { |
| | | saveParentFeeProfit(order, future_profit_bonus_parameters); |
| | | } |
| | | } else { |
| | | BigDecimal amount = BigDecimal.valueOf(order.getVolume()).add(BigDecimal.valueOf(order.getProfit())); |
| | | walletService.updateMoney(order.getSymbol(), order.getPartyId(), amount, BigDecimal.ZERO, |
| | | Constants.MONEYLOG_CATEGORY_CONTRACT, Constants.WALLET, Constants.DELIVERY_MONEYLOG_CONTENT_CONTRACT_CLOSE, |
| | | "交割合约亏损退还(手动盈亏%),订单号[" + order.getOrderNo() + "]"); |
| | | } |
| | | updateById(order); |
| | | cache.remove(order.getOrderNo()); |
| | | FuturesOrder futuresOld = (FuturesOrder) RedisUtil.get(FuturesRedisKeys.FUTURES_SUBMITTED_ORDERNO + order.getOrderNo()); |
| | | RedisUtil.del(FuturesRedisKeys.FUTURES_SUBMITTED_ORDERNO + order.getOrderNo()); |
| | | Double futuresAssets = (Double) RedisUtil.get(FuturesRedisKeys.FUTURES_ASSETS_PARTY_ID + order.getPartyId().toString()); |
| | | Double futuresAssetsProfit = (Double) RedisUtil.get(FuturesRedisKeys.FUTURES_ASSETS_PROFIT_PARTY_ID + order.getPartyId().toString()); |
| | | if (null != futuresOld) { |
| | | Map<String, Double> futuresAssetsOld = this.walletService.getMoneyFuturesByOrder(futuresOld); |
| | | RedisUtil.set(FuturesRedisKeys.FUTURES_ASSETS_PARTY_ID + order.getPartyId().toString(), |
| | | Arith.add(null == futuresAssets ? 0.000D : futuresAssets, 0 - futuresAssetsOld.get("money_futures"))); |
| | | RedisUtil.set(FuturesRedisKeys.FUTURES_ASSETS_PROFIT_PARTY_ID + order.getPartyId().toString(), |
| | | Arith.add(null == futuresAssetsProfit ? 0.000D : futuresAssetsProfit, 0 - futuresAssetsOld.get("money_futures_profit"))); |
| | | } |
| | | this.userDataService.saveFuturesClose(order); |
| | | User party = userService.getById(order.getPartyId()); |
| | | party.setWithdrawLimitNowAmount(new BigDecimal(Arith.add(party.getWithdrawLimitNowAmount().doubleValue(), order.getVolume()))); |
| | | userService.updateById(party); |
| | | tipService.deleteTip(order.getUuid()); |
| | | } |
| | | |
| | | /** 按后台设定的 manualProfitPercent 计算盈亏,与买卖方向、现价无关 */ |
| | | private void applyManualProfitPercentToOrder(FuturesOrder order) { |
| | | double profit = Arith.mul(order.getVolume(), Arith.div(order.getManualProfitPercent(), 100.0)); |
| | | DecimalFormat df = new DecimalFormat("#.##"); |
| | | order.setProfit(Double.valueOf(df.format(profit))); |
| | | } |
| | | |
| | | |
| | | public List<FuturesOrder> findByHourAndSate(String state, String rolename) { |
| | | return baseMapper.findByHourAndSate(state, rolename, new Date()); |