| | |
| | | |
| | | if (!UpGridElement.isHasShortOrder() && shortEntryPrice.compareTo(newLongFirst) > 0) { |
| | | |
| | | //挂空仓条件单 |
| | | TraderParam upShortTraderParam = UpGridElement.getShortTraderParam(); |
| | | executor.placeConditionalEntryOrder( |
| | | placeEntryOrderWithPreFlag(UpGridElement, false, |
| | | upShortTraderParam.getEntryPrice(), |
| | | FuturesPriceTrigger.RuleEnum.NUMBER_2, |
| | | negate(upShortTraderParam.getQuantity()), |
| | | orderId -> |
| | | { |
| | | shortEntryTraderIdParam( |
| | | UpGridElement, |
| | | orderId, |
| | | true |
| | | ); |
| | | }, |
| | | null |
| | | ); |
| | | negate(upShortTraderParam.getQuantity())); |
| | | } |
| | | int i = gridElement.getUpId(); |
| | | GridElement downGridElement = GridElement.findById(i); |
| | |
| | | downGridPrice.compareTo(longEntryPrice) <= 0 && |
| | | downGridPrice.compareTo(shortEntryPrice) >= 0 |
| | | ){ |
| | | executor.placeConditionalEntryOrder( |
| | | placeEntryOrderWithPreFlag(downGridElement, false, |
| | | downShortTraderParam.getEntryPrice(), |
| | | FuturesPriceTrigger.RuleEnum.NUMBER_1, |
| | | negate(downShortTraderParam.getQuantity()), |
| | | orderId -> |
| | | { |
| | | shortEntryTraderIdParam( |
| | | downGridElement, |
| | | orderId, |
| | | true |
| | | ); |
| | | }, |
| | | null |
| | | ); |
| | | negate(downShortTraderParam.getQuantity())); |
| | | |
| | | } |
| | | |
| | |
| | | !downGridElement.isHasLongOrder() && |
| | | downGridPrice.compareTo(longEntryPrice) <= 0 |
| | | ){ |
| | | executor.placeConditionalEntryOrder( |
| | | placeEntryOrderWithPreFlag(downGridElement, true, |
| | | downLongTraderParam.getEntryPrice(), |
| | | FuturesPriceTrigger.RuleEnum.NUMBER_1, |
| | | downLongTraderParam.getQuantity(), |
| | | orderId -> |
| | | { |
| | | longEntryTraderIdParam( |
| | | downGridElement, |
| | | orderId, |
| | | true |
| | | ); |
| | | }, |
| | | null |
| | | ); |
| | | downLongTraderParam.getQuantity()); |
| | | } |
| | | } |
| | | } |
| | |
| | | if (UpGridElement != null) { |
| | | |
| | | if (!UpGridElement.isHasLongOrder() && longEntryPrice.compareTo(newLongFirst) < 0) { |
| | | //挂多仓条件单 |
| | | TraderParam upLongTraderParam = UpGridElement.getLongTraderParam(); |
| | | executor.placeConditionalEntryOrder( |
| | | placeEntryOrderWithPreFlag(UpGridElement, true, |
| | | upLongTraderParam.getEntryPrice(), |
| | | FuturesPriceTrigger.RuleEnum.NUMBER_1, |
| | | config.getQuantity(), |
| | | orderId -> |
| | | { |
| | | longEntryTraderIdParam( |
| | | UpGridElement, |
| | | orderId, |
| | | true |
| | | ); |
| | | }, |
| | | null |
| | | ); |
| | | config.getQuantity()); |
| | | } |
| | | |
| | | int i = gridElement.getDownId(); |
| | |
| | | downGridPrice.compareTo(shortEntryPrice) >= 0 && |
| | | downGridPrice.compareTo(longEntryPrice) <= 0 |
| | | ){ |
| | | executor.placeConditionalEntryOrder( |
| | | placeEntryOrderWithPreFlag(downGridElement, true, |
| | | downLongTraderParam.getEntryPrice(), |
| | | FuturesPriceTrigger.RuleEnum.NUMBER_2, |
| | | config.getQuantity(), |
| | | orderId -> |
| | | { |
| | | longEntryTraderIdParam( |
| | | downGridElement, |
| | | orderId, |
| | | true |
| | | ); |
| | | }, |
| | | null |
| | | ); |
| | | config.getQuantity()); |
| | | |
| | | } |
| | | |
| | |
| | | downGridPrice.compareTo(shortEntryPrice) >= 0 |
| | | ){ |
| | | |
| | | executor.placeConditionalEntryOrder( |
| | | placeEntryOrderWithPreFlag(downGridElement, false, |
| | | shortTraderParam.getEntryPrice(), |
| | | FuturesPriceTrigger.RuleEnum.NUMBER_2, |
| | | negate(config.getQuantity()), |
| | | orderId -> |
| | | { |
| | | shortEntryTraderIdParam( |
| | | downGridElement, |
| | | orderId, |
| | | true |
| | | ); |
| | | }, |
| | | null |
| | | ); |
| | | negate(config.getQuantity())); |
| | | } |
| | | } |
| | | } |
| | |
| | | Integer upId = baseGridElement.getUpId(); |
| | | GridElement upGridElementOne = GridElement.findById(upId); |
| | | BigDecimal longTp = upGridElementOne.getGridPrice(); |
| | | executor.placeConditionalEntryOrder( |
| | | placeEntryOrderWithPreFlag(upGridElementOne, true, |
| | | longTp, |
| | | FuturesPriceTrigger.RuleEnum.NUMBER_1, |
| | | config.getQuantity(), |
| | | orderId -> { |
| | | longEntryTraderIdParam( |
| | | upGridElementOne, |
| | | orderId, |
| | | true |
| | | ); |
| | | }, |
| | | null); |
| | | config.getQuantity()); |
| | | Integer downId = baseGridElement.getDownId(); |
| | | GridElement downGridElementOne = GridElement.findById(downId); |
| | | BigDecimal shortTp = downGridElementOne.getGridPrice(); |
| | | executor.placeConditionalEntryOrder( |
| | | placeEntryOrderWithPreFlag(downGridElementOne, false, |
| | | shortTp, |
| | | FuturesPriceTrigger.RuleEnum.NUMBER_2, |
| | | negate(config.getQuantity()), |
| | | orderId -> { |
| | | shortEntryTraderIdParam( |
| | | downGridElementOne, |
| | | orderId, |
| | | true |
| | | ); |
| | | }, |
| | | null); |
| | | negate(config.getQuantity())); |
| | | |
| | | state = StrategyState.ACTIVE; |
| | | } |
| | |
| | | |
| | | if (!UpGridElement.isHasShortOrder() && shortEntryPrice.compareTo(newLongFirst) > 0) { |
| | | |
| | | //挂空仓条件单 |
| | | TraderParam upShortTraderParam = UpGridElement.getShortTraderParam(); |
| | | executor.placeConditionalEntryOrder( |
| | | placeEntryOrderWithPreFlag(UpGridElement, false, |
| | | upShortTraderParam.getEntryPrice(), |
| | | FuturesPriceTrigger.RuleEnum.NUMBER_2, |
| | | negate(upShortTraderParam.getQuantity()), |
| | | orderId -> |
| | | { |
| | | shortEntryTraderIdParam( |
| | | UpGridElement, |
| | | orderId, |
| | | true |
| | | ); |
| | | }, |
| | | null |
| | | ); |
| | | negate(upShortTraderParam.getQuantity())); |
| | | } |
| | | int i = UpGridElement.getId() + 2; |
| | | GridElement downGridElement = GridElement.findById(i); |
| | |
| | | downGridPrice.compareTo(longEntryPrice) <= 0 && |
| | | downGridPrice.compareTo(shortEntryPrice) >= 0 |
| | | ){ |
| | | executor.placeConditionalEntryOrder( |
| | | placeEntryOrderWithPreFlag(downGridElement, false, |
| | | downShortTraderParam.getEntryPrice(), |
| | | FuturesPriceTrigger.RuleEnum.NUMBER_1, |
| | | negate(downShortTraderParam.getQuantity()), |
| | | orderId -> |
| | | { |
| | | shortEntryTraderIdParam( |
| | | downGridElement, |
| | | orderId, |
| | | true |
| | | ); |
| | | }, |
| | | null |
| | | ); |
| | | negate(downShortTraderParam.getQuantity())); |
| | | |
| | | } |
| | | |
| | |
| | | !downGridElement.isHasLongOrder() && |
| | | downGridPrice.compareTo(longEntryPrice) <= 0 |
| | | ){ |
| | | executor.placeConditionalEntryOrder( |
| | | placeEntryOrderWithPreFlag(downGridElement, true, |
| | | downLongTraderParam.getEntryPrice(), |
| | | FuturesPriceTrigger.RuleEnum.NUMBER_1, |
| | | downLongTraderParam.getQuantity(), |
| | | orderId -> |
| | | { |
| | | longEntryTraderIdParam( |
| | | downGridElement, |
| | | orderId, |
| | | true |
| | | ); |
| | | }, |
| | | null |
| | | ); |
| | | downLongTraderParam.getQuantity()); |
| | | } |
| | | } |
| | | } |
| | |
| | | if (UpGridElement != null) { |
| | | |
| | | if (!UpGridElement.isHasLongOrder() && longEntryPrice.compareTo(newLongFirst) < 0) { |
| | | //挂多仓条件单 |
| | | TraderParam upLongTraderParam = UpGridElement.getLongTraderParam(); |
| | | executor.placeConditionalEntryOrder( |
| | | placeEntryOrderWithPreFlag(UpGridElement, true, |
| | | upLongTraderParam.getEntryPrice(), |
| | | FuturesPriceTrigger.RuleEnum.NUMBER_1, |
| | | config.getQuantity(), |
| | | orderId -> |
| | | { |
| | | longEntryTraderIdParam( |
| | | UpGridElement, |
| | | orderId, |
| | | true |
| | | ); |
| | | }, |
| | | null |
| | | ); |
| | | config.getQuantity()); |
| | | } |
| | | |
| | | int i = UpGridElement.getId() - 2; |
| | |
| | | downGridPrice.compareTo(shortEntryPrice) >= 0 && |
| | | downGridPrice.compareTo(longEntryPrice) <= 0 |
| | | ){ |
| | | executor.placeConditionalEntryOrder( |
| | | placeEntryOrderWithPreFlag(downGridElement, true, |
| | | downLongTraderParam.getEntryPrice(), |
| | | FuturesPriceTrigger.RuleEnum.NUMBER_2, |
| | | config.getQuantity(), |
| | | orderId -> |
| | | { |
| | | longEntryTraderIdParam( |
| | | downGridElement, |
| | | orderId, |
| | | true |
| | | ); |
| | | }, |
| | | null |
| | | ); |
| | | config.getQuantity()); |
| | | |
| | | } |
| | | |
| | |
| | | downGridPrice.compareTo(shortEntryPrice) >= 0 |
| | | ){ |
| | | |
| | | executor.placeConditionalEntryOrder( |
| | | placeEntryOrderWithPreFlag(downGridElement, false, |
| | | shortTraderParam.getEntryPrice(), |
| | | FuturesPriceTrigger.RuleEnum.NUMBER_2, |
| | | negate(config.getQuantity()), |
| | | orderId -> |
| | | { |
| | | shortEntryTraderIdParam( |
| | | downGridElement, |
| | | orderId, |
| | | true |
| | | ); |
| | | }, |
| | | null |
| | | ); |
| | | negate(config.getQuantity())); |
| | | } |
| | | } |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * 预设标志位后提交条件开仓单,防止异步回调导致的竞态重复挂单。 |
| | | * |
| | | * <p>在调用 {@link GateTradeExecutor#placeConditionalEntryOrder} 之前同步设置 |
| | | * {@code isHasLongOrder / isHasShortOrder},关闭 WS 线程与 Executor 线程之间的 |
| | | * 检查-下单时间窗口。API 失败时自动回滚标志位。 |
| | | * |
| | | * @param gridElement 目标网格元素 |
| | | * @param isLong true=多仓下单,false=空仓下单 |
| | | * @param triggerPrice 触发价 |
| | | * @param rule 触发规则 |
| | | * @param size 开仓张数 |
| | | */ |
| | | private void placeEntryOrderWithPreFlag(GridElement gridElement, boolean isLong, |
| | | BigDecimal triggerPrice, |
| | | FuturesPriceTrigger.RuleEnum rule, |
| | | String size) { |
| | | if (isLong) { |
| | | gridElement.setHasLongOrder(true); |
| | | } else { |
| | | gridElement.setHasShortOrder(true); |
| | | } |
| | | executor.placeConditionalEntryOrder(triggerPrice, rule, size, |
| | | orderId -> { |
| | | if (isLong) { |
| | | longEntryTraderIdParam(gridElement, orderId, true); |
| | | } else { |
| | | shortEntryTraderIdParam(gridElement, orderId, true); |
| | | } |
| | | }, |
| | | () -> { |
| | | if (isLong) { |
| | | gridElement.setHasLongOrder(false); |
| | | gridElement.setLongOrderId(null); |
| | | } else { |
| | | gridElement.setHasShortOrder(false); |
| | | gridElement.setShortOrderId(null); |
| | | } |
| | | GridElement.refreshIndices(); |
| | | log.warn("[Gate] 条件单创建失败,回滚标志位 gridId:{}, isLong:{}", gridElement.getId(), isLong); |
| | | } |
| | | ); |
| | | } |
| | | |
| | | /** |
| | | * 根据持仓和当前价格计算未实现盈亏。 |
| | | * |
| | | * <h3>正向合约公式</h3> |