From 5e57de9b12ee136e45ce5754c7fe2e7eb12af05a Mon Sep 17 00:00:00 2001
From: zj <1772600164@qq.com>
Date: Fri, 12 Jun 2026 18:35:45 +0800
Subject: [PATCH] 1
---
trading-order-service/src/main/java/com/yami/trading/service/future/FuturesOrderService.java | 216 +++++++++++++++++++++++++++++++++++++++++++++--------
1 files changed, 181 insertions(+), 35 deletions(-)
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/future/FuturesOrderService.java b/trading-order-service/src/main/java/com/yami/trading/service/future/FuturesOrderService.java
index f1c05e2..c96ed88 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/future/FuturesOrderService.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/future/FuturesOrderService.java
@@ -208,6 +208,87 @@
* @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;
@@ -229,6 +310,7 @@
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);
@@ -330,7 +412,7 @@
realtime = realtime_list.get(0);
}
if (null == realtime) {
- throw new BusinessException(1, "请稍后再试");
+ throw new BusinessException(1, "行情获取失败,请稍后再试");
}
Double volume = futuresOrder.getVolume();
@@ -454,41 +536,45 @@
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()));
+ }
}
}
}
@@ -642,6 +728,11 @@
order.setCloseTime(System.currentTimeMillis() / 1000);
order.setState(FuturesOrder.STATE_CREATED);
+ if (order.getManualProfitPercent() != null) {
+ settleByManualProfitPercent(order);
+ return;
+ }
+
String ProfitLoss = null;
/**
* 计算盈亏状态
@@ -704,11 +795,13 @@
"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";
}
@@ -881,6 +974,59 @@
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());
--
Gitblit v1.9.3