| | |
| | | int baseQty = Integer.parseInt(config.getBaseQuantity()); |
| | | int gridCount = baseQty / qty; |
| | | GridElement entryElem = GridElement.findById(gridId); |
| | | if (gridCount <= 0 || filledQty < qty) { |
| | | if (gridCount <= 0 || filledQty <= 0) { |
| | | // 早期返回需重置防重入标记 |
| | | if (entryElem != null) { entryElem.setExtendStopLossInProgress(false); } |
| | | return; |
| | | } |
| | | |
| | | // [Gate] 止损只针对初始开仓仓位(baseQuantity),加仓部分只做止盈 |
| | | int totalOrders = filledQty / qty; |
| | | // [Gate] 止损只针对初始开仓仓位(baseQuantity),加仓部分只做止盈; |
| | | // 持仓不足一个网格量时也按剩余张数挂一张止损(手动重建场景,避免裸奔) |
| | | int slSize = Math.min(filledQty, baseQty); |
| | | int totalOrders = slSize / qty; |
| | | int remainder = slSize % qty; |
| | | int[] orders = new int[gridCount]; |
| | | |
| | | if (gridCount == 1) { |
| | |
| | | for (int i = 0; i < gridCount; i++) { |
| | | if (orders[i] > 0) { totalOrdersToPlace += orders[i]; } |
| | | } |
| | | if (remainder > 0) { totalOrdersToPlace += 1; } |
| | | if (totalOrdersToPlace == 0) { |
| | | if (entryElem != null) { entryElem.setExtendStopLossInProgress(false); } |
| | | return; |
| | |
| | | for (int i = 0; i < gridCount; i++) { |
| | | if (orders[i] > 0) { |
| | | int sgId = gridId - 2 - i; |
| | | placeStopLossOrders(sgId, orders[i], qty, FuturesPriceTrigger.RuleEnum.NUMBER_2, |
| | | placeStopLossOrders(sgId, orders[i], String.valueOf(qty), FuturesPriceTrigger.RuleEnum.NUMBER_2, |
| | | ORDER_TYPE_CLOSE_LONG, true, remainCount, entryElem); |
| | | if (detail.length() > 0) { |
| | | detail.append(" "); |
| | | } |
| | | detail.append(sgId).append("x").append(orders[i]); |
| | | } |
| | | } |
| | | // 不足一个网格量的余数:单独挂一张止损 |
| | | if (remainder > 0) { |
| | | int sgId = gridId - 2 - totalOrders; |
| | | placeStopLossOrders(sgId, 1, String.valueOf(remainder), FuturesPriceTrigger.RuleEnum.NUMBER_2, |
| | | ORDER_TYPE_CLOSE_LONG, true, remainCount, entryElem); |
| | | if (detail.length() > 0) { |
| | | detail.append(" "); |
| | | } |
| | | detail.append(sgId).append("x").append(remainder); |
| | | } |
| | | |
| | | log.info("[Gate] 多仓追挂止损, 成交{}张, gridId:{}, 网格数:{}, 分配:{}", |
| | |
| | | int baseQty = Integer.parseInt(config.getBaseQuantity()); |
| | | int gridCount = baseQty / qty; |
| | | GridElement entryElem = GridElement.findById(gridId); |
| | | if (gridCount <= 0 || filledQty < qty) { |
| | | if (gridCount <= 0 || filledQty <= 0) { |
| | | // 早期返回需重置防重入标记 |
| | | if (entryElem != null) { entryElem.setExtendStopLossInProgress(false); } |
| | | return; |
| | | } |
| | | |
| | | // [Gate] 止损只针对初始开仓仓位(baseQuantity),加仓部分只做止盈 |
| | | int totalOrders = filledQty / qty; |
| | | // [Gate] 止损只针对初始开仓仓位(baseQuantity),加仓部分只做止盈; |
| | | // 持仓不足一个网格量时也按剩余张数挂一张止损(手动重建场景,避免裸奔) |
| | | int slSize = Math.min(filledQty, baseQty); |
| | | int totalOrders = slSize / qty; |
| | | int remainder = slSize % qty; |
| | | int[] orders = new int[gridCount]; |
| | | |
| | | if (gridCount == 1) { |
| | |
| | | for (int i = 0; i < gridCount; i++) { |
| | | if (orders[i] > 0) { totalOrdersToPlace += orders[i]; } |
| | | } |
| | | if (remainder > 0) { totalOrdersToPlace += 1; } |
| | | if (totalOrdersToPlace == 0) { |
| | | if (entryElem != null) { entryElem.setExtendStopLossInProgress(false); } |
| | | return; |
| | |
| | | for (int i = 0; i < gridCount; i++) { |
| | | if (orders[i] > 0) { |
| | | int sgId = gridId + 2 + i; |
| | | placeStopLossOrders(sgId, orders[i], qty, FuturesPriceTrigger.RuleEnum.NUMBER_1, |
| | | placeStopLossOrders(sgId, orders[i], String.valueOf(qty), FuturesPriceTrigger.RuleEnum.NUMBER_1, |
| | | ORDER_TYPE_CLOSE_SHORT, false, remainCount, entryElem); |
| | | if (detail.length() > 0) { |
| | | detail.append(" "); |
| | | } |
| | | detail.append(sgId).append("x").append(orders[i]); |
| | | } |
| | | } |
| | | // 不足一个网格量的余数:单独挂一张止损 |
| | | if (remainder > 0) { |
| | | int sgId = gridId + 2 + totalOrders; |
| | | placeStopLossOrders(sgId, 1, String.valueOf(remainder), FuturesPriceTrigger.RuleEnum.NUMBER_1, |
| | | ORDER_TYPE_CLOSE_SHORT, false, remainCount, entryElem); |
| | | if (detail.length() > 0) { |
| | | detail.append(" "); |
| | | } |
| | | detail.append(sgId).append("x").append(remainder); |
| | | } |
| | | |
| | | log.info("[Gate] 空仓追挂止损, 成交{}张, gridId:{}, 网格数:{}, 分配:{}", |
| | |
| | | /** |
| | | * 在指定网格位置挂 count 个独立止损单,每个 size 张。 |
| | | */ |
| | | private void placeStopLossOrders(int gridId, int count, int qty, |
| | | private void placeStopLossOrders(int gridId, int count, String qtyStr, |
| | | FuturesPriceTrigger.RuleEnum rule, |
| | | String orderType, boolean isLong, |
| | | AtomicInteger remainCount, |
| | |
| | | return; |
| | | } |
| | | BigDecimal triggerPrice = elem.getGridPrice(); |
| | | String size = isLong ? negate(qtyStr) : qtyStr; |
| | | for (int i = 0; i < count; i++) { |
| | | String size = isLong ? negate(String.valueOf(qty)) : String.valueOf(qty); |
| | | int finalGridId = gridId; |
| | | int finalI = i; |
| | | executor.placeTakeProfit( |