| | |
| | | } |
| | | |
| | | /** |
| | | * 构建容错的 JSON 序列化器,跳过 {@code finishAs} 字段的反序列化。 |
| | | * 构建容错的 JSON 序列化器,跳过部分枚举不完整字段的反序列化。 |
| | | * |
| | | * <p>gate-api SDK 的 {@code FuturesOrder.FinishAsEnum} 枚举不完整,缺少 |
| | | * {@code price_rate_proteced}(价格保护)等 Gate 实际会返回的值。反序列化未知 |
| | | * 枚举值时 {@code fromValue} 会抛 {@link IllegalArgumentException},导致已成功 |
| | | * 提交的订单被误判为失败(如日志 {@code Unexpected value 'price_rate_proteced'})。 |
| | | * 业务不使用 finishAs 字段,因此通过 Gson 排除策略直接跳过其解析。 |
| | | * <p>gate-api SDK 的枚举定义滞后于交易所实际返回值,反序列化未知枚举值时 |
| | | * {@code fromValue} 会抛 {@link IllegalArgumentException},导致接口被误判为失败。 |
| | | * 已确认业务不使用以下字段,因此通过 Gson 排除策略直接跳过其解析: |
| | | * <ul> |
| | | * <li>{@code finishAs}:{@code FuturesOrder.FinishAsEnum} 缺少 |
| | | * {@code price_rate_protected}(价格保护)等值(如日志 |
| | | * {@code Unexpected value 'price_rate_proteced'});</li> |
| | | * <li>{@code posMarginMode}:{@code FuturesPriceTriggeredOrder.PosMarginModeEnum} |
| | | * 只定义 {@code cross}/{@code dual},而 {@code cancelPriceTriggeredOrderList} |
| | | * 会返回组合值 {@code cross|dual}(如日志 {@code Unexpected value 'cross|dual'})。</li> |
| | | * </ul> |
| | | */ |
| | | private static JSON buildLenientJson() { |
| | | JSON json = new JSON(); |
| | |
| | | .setExclusionStrategies(new ExclusionStrategy() { |
| | | @Override |
| | | public boolean shouldSkipField(FieldAttributes f) { |
| | | return "finishAs".equals(f.getName()); |
| | | if ("finishAs".equals(f.getName())) { |
| | | return true; |
| | | } |
| | | // 仅跳过 FuturesPriceTriggeredOrder 的 posMarginMode,避免误伤 |
| | | // FuturesOrder / Position 的同名字段(二者语义为 isolated/cross) |
| | | return "posMarginMode".equals(f.getName()) |
| | | && FuturesPriceTriggeredOrder.class.equals(f.getDeclaringClass()); |
| | | } |
| | | |
| | | @Override |
| | |
| | | config.isPriceDriveEnabled() && |
| | | longActive == false && |
| | | longPositionSize.compareTo(BigDecimal.ZERO) == 0){ |
| | | processShortGrid(closePrice); |
| | | processLongGrid(closePrice); |
| | | } |
| | | |
| | | |
| | |
| | | config.isPriceDriveEnabled() && |
| | | shortActive == false && |
| | | shortPositionSize.compareTo(BigDecimal.ZERO) == 0){ |
| | | processLongGrid(closePrice); |
| | | processShortGrid(closePrice); |
| | | } |
| | | } |
| | | |
| | |
| | | generateShortQueue(); |
| | | generateLongQueue(); |
| | | updateGridElements(); |
| | | |
| | | GridElement baseGridElement = GridElement.findById(0); |
| | | baseGridElement.setLongOrderId(baseLongTraderParam.getEntryOrderId()); |
| | | baseGridElement.setHasLongOrder(true); |
| | | baseGridElement.setShortOrderId(baseShortTraderParam.getEntryOrderId()); |
| | | baseGridElement.setHasShortOrder(true); |
| | | |
| | | // // 空仓止损对应的多仓止盈:多仓止盈挂在ID=3 |
| | | // int tpGridIdLong = 3; |
| | |
| | | } |
| | | |
| | | |
| | | private void processShortGrid(BigDecimal currentPrice) { |
| | | /** 多仓仓位归零后,在当前价上方最近网格重新挂多单(遍历 totalLongPriceQueue 升序)。 */ |
| | | private void processLongGrid(BigDecimal currentPrice) { |
| | | BigDecimal matched = BigDecimal.ZERO; |
| | | synchronized (totalLongPriceQueue) { |
| | | for (BigDecimal p : totalLongPriceQueue) { |
| | |
| | | |
| | | } |
| | | |
| | | private void processLongGrid(BigDecimal currentPrice) { |
| | | /** 空仓仓位归零后,在当前价下方最近网格重新挂空单(遍历 totalShortPriceQueue 降序)。 */ |
| | | private void processShortGrid(BigDecimal currentPrice) { |
| | | BigDecimal matched = BigDecimal.ZERO; |
| | | synchronized (totalShortPriceQueue) { |
| | | for (BigDecimal p : totalShortPriceQueue) { |
| | |
| | | GridElement finalCancelCursor = cancelCursor; |
| | | executor.cancelConditionalOrder(shortOrderId, oid -> { |
| | | shortEntryTraderIdParam(finalCancelCursor, shortOrderId, false); |
| | | log.info("[Gate] 空仓仓位归零, 取消gridId:{}的多单{}", finalCancelCursor.getId(), shortOrderId); |
| | | log.info("[Gate] 空仓仓位归零, 取消gridId:{}的空单{}", finalCancelCursor.getId(), shortOrderId); |
| | | }); |
| | | } |
| | | } |
| | |
| | | if (!newEntryGrid.isHasShortOrder() && !hasShortOrderAbove){ |
| | | BigDecimal triggerPrice = newEntryGrid.getGridPrice(); |
| | | String size = quantity; |
| | | log.info("[Gate] 空仓仓位归零 gridId:{}, 挂{}基础张多单", |
| | | log.info("[Gate] 空仓仓位归零 gridId:{}, 挂{}基础张空单", |
| | | newEntryGrid.getId(), size); |
| | | newEntryGrid.getShortTraderParam().setQuantity(size); |
| | | placeEntryOrderWithPreFlag(newEntryGrid, false, triggerPrice, |