| | |
| | | |
| | | log.info("[Gate] 重置策略,开始第{}轮...", currentRound); |
| | | state = StrategyState.STOPPED; |
| | | try { |
| | | futuresApi.cancelPriceTriggeredOrderList(SETTLE, config.getContract()); |
| | | } catch (ApiException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | closeExistingPositions(); |
| | | // 提交到 executor 末尾:单线程FIFO保证前面所有平仓/取消任务完成后才重置 |
| | | // 关键修复:取消+平仓+延时+重启必须整体放进 executor 队列末尾,让上一轮排队的 |
| | | // 挂单任务先执行完(挂到交易所),随后的 cancel 才能取消到它们。若 cancel 仍留在 |
| | | // WS 线程同步执行,会早于上一轮挂单任务,取消不到"尚未挂出"的单(竞态)。 |
| | | executor.submitTask(() -> { |
| | | try { |
| | | futuresApi.cancelPriceTriggeredOrderList(SETTLE, config.getContract()); |
| | | } catch (ApiException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | closeExistingPositions(); |
| | | try { Thread.sleep(3000); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } |
| | | // 注意:startGrid() 会将 currentRound 归零,这里需要保留 |
| | | int savedRound = currentRound; |
| | |
| | | lastShortStopLossGridId = Integer.MAX_VALUE; |
| | | // [Gate-需求2] 加仓后先撤空仓所有止盈+止损,再查交易所持仓后重挂 |
| | | cancelAllShortTakeProfitsAndStopLosses(); |
| | | // REST 查询可能因交易所延迟返回旧值,与 WS 本地缓存取最大值兜底 |
| | | int posSize = Math.max(queryPositionSize(Position.ModeEnum.DUAL_SHORT), shortPositionSize.intValue()); |
| | | // REST/WS 持仓可能因交易所延迟返回旧值(仓位归零后重开甚至为 0), |
| | | // 与本次成交张数 filledQty 取最大值兜底,避免 posSize=0 导致止盈止损全部跳过 |
| | | int posSize = Math.max(Math.max(queryPositionSize(Position.ModeEnum.DUAL_SHORT), shortPositionSize.intValue()), filledQty); |
| | | extendShortStopLoss(posSize, shortGridElement.getId()); |
| | | // [Gate] 止盈挂单:超出基础仓位的部分,挂在多仓第一止损位 |
| | | if (GateConfig.EXCESS_TP_CONCENTRATED.equals(config.getPlaceExcessTakeProfit())) { |
| | |
| | | lastLongStopLossGridId = Integer.MAX_VALUE; |
| | | // [Gate-需求2] 加仓后先撤多仓所有止盈+止损,再查交易所持仓后重挂 |
| | | cancelAllLongTakeProfitsAndStopLosses(); |
| | | // REST 查询可能因交易所延迟返回旧值,与 WS 本地缓存取最大值兜底 |
| | | int posSize = Math.max(queryPositionSize(Position.ModeEnum.DUAL_LONG), longPositionSize.intValue()); |
| | | // REST/WS 持仓可能因交易所延迟返回旧值(仓位归零后重开甚至为 0), |
| | | // 与本次成交张数 filledQty 取最大值兜底,避免 posSize=0 导致止盈止损全部跳过 |
| | | int posSize = Math.max(Math.max(queryPositionSize(Position.ModeEnum.DUAL_LONG), longPositionSize.intValue()), filledQty); |
| | | extendLongStopLoss(posSize, longGridElement.getId()); |
| | | // [Gate] 止盈挂单:超出基础仓位的部分,挂在空仓第一止损位 |
| | | if (GateConfig.EXCESS_TP_CONCENTRATED.equals(config.getPlaceExcessTakeProfit())) { |