fix(trade): 优化网格交易日志输出并实现市价止盈机制
- 简化K线数据日志输出,只保留收盘价和完结状态
- 添加网格队列操作的详细日志记录
- 修改空头队列排序逻辑为降序排列
- 移除队列操作中的跳过数量统计
- 实现止盈条件单创建失败时的市价止盈功能
- 添加市价止盈方法处理平仓操作
3 files modified
1 files added
| | |
| | | for (int i = 0; i < matched.size(); i++) { |
| | | min = min.multiply(BigDecimal.ONE.subtract(step)).setScale(1, RoundingMode.HALF_UP); |
| | | shortPriceQueue.add(min); |
| | | log.info("[Gate] 空队列增加:{}", min); |
| | | } |
| | | shortPriceQueue.sort(BigDecimal::compareTo); |
| | | |
| | | shortPriceQueue.sort((a, b) -> b.compareTo(a)); |
| | | |
| | | log.info("[Gate] 现空队列:{}", shortPriceQueue); |
| | | } |
| | |
| | | synchronized (longPriceQueue) { |
| | | BigDecimal first = longPriceQueue.isEmpty() ? matched.get(matched.size() - 1) : longPriceQueue.get(0); |
| | | BigDecimal step = config.getGridRate(); |
| | | int added = 0; |
| | | for (int i = 1; i <= matched.size(); i++) { |
| | | BigDecimal elem = first.multiply(BigDecimal.ONE.subtract(step.multiply(BigDecimal.valueOf(i)))).setScale(1, RoundingMode.HALF_UP); |
| | | if (longEntryPrice.compareTo(BigDecimal.ZERO) > 0 |
| | | && elem.subtract(longEntryPrice).abs().compareTo(longEntryPrice.multiply(step)) < 0) { |
| | | log.info("[Gate] 多队列跳过:{}", elem); |
| | | continue; |
| | | } |
| | | longPriceQueue.add(elem); |
| | | added++; |
| | | |
| | | log.info("[Gate] 多队列增加:{}", elem); |
| | | } |
| | | longPriceQueue.sort(BigDecimal::compareTo); |
| | | while (longPriceQueue.size() > config.getGridQueueSize()) { |
| | | longPriceQueue.remove(longPriceQueue.size() - 1); |
| | | } |
| | | log.info("[Gate] 现多队列:{}, 跳过{}个(贴近多仓均价)", longPriceQueue, matched.size() - added); |
| | | log.info("[Gate] 现多队列:{}", longPriceQueue); |
| | | } |
| | | } |
| | | |
| | |
| | | for (int i = 0; i < matched.size(); i++) { |
| | | max = max.multiply(BigDecimal.ONE.add(step)).setScale(1, RoundingMode.HALF_UP); |
| | | longPriceQueue.add(max); |
| | | |
| | | log.info("[Gate] 多队列增加:{}", max); |
| | | } |
| | | longPriceQueue.sort(BigDecimal::compareTo); |
| | | |
| | |
| | | synchronized (shortPriceQueue) { |
| | | BigDecimal first = shortPriceQueue.isEmpty() ? matched.get(0) : shortPriceQueue.get(0); |
| | | BigDecimal step = config.getGridRate(); |
| | | int added = 0; |
| | | for (int i = 1; i <= matched.size(); i++) { |
| | | BigDecimal elem = first.multiply(BigDecimal.ONE.add(step.multiply(BigDecimal.valueOf(i)))).setScale(1, RoundingMode.HALF_UP); |
| | | if (shortEntryPrice.compareTo(BigDecimal.ZERO) > 0 |
| | | && elem.subtract(shortEntryPrice).abs().compareTo(shortEntryPrice.multiply(step)) < 0) { |
| | | |
| | | log.info("[Gate] 空队列跳过:{}", elem); |
| | | continue; |
| | | } |
| | | shortPriceQueue.add(elem); |
| | | added++; |
| | | |
| | | log.info("[Gate] 空队列增加:{}", elem); |
| | | } |
| | | shortPriceQueue.sort((a, b) -> b.compareTo(a)); |
| | | while (shortPriceQueue.size() > config.getGridQueueSize()) { |
| | | shortPriceQueue.remove(shortPriceQueue.size() - 1); |
| | | } |
| | | log.info("[Gate] 现空队列:{}, 跳过{}个(贴近空仓均价)", shortPriceQueue, matched.size() - added); |
| | | log.info("[Gate] 现空队列:{}", shortPriceQueue); |
| | | } |
| | | } |
| | | |
| | |
| | | log.info("[TradeExec] 止盈单已创建, 触发价:{}, 类型:{}, size:{}, id:{}", |
| | | triggerPrice, orderType, size, response.getId()); |
| | | } catch (Exception e) { |
| | | log.error("[TradeExec] 止盈单创建失败, 触发价:{}, size:{}", triggerPrice, size, e); |
| | | log.error("[TradeExec] 止盈单创建失败, 触发价:{}, size:{}, 立即市价止盈", triggerPrice, size, e); |
| | | marketClose(size); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | /** |
| | | * 市价止盈:在止盈条件单创建失败时立即市价平仓。 |
| | | * size 与止盈单保持一致(负=平多,正=平空)。 |
| | | */ |
| | | private void marketClose(String size) { |
| | | try { |
| | | FuturesOrder order = new FuturesOrder(); |
| | | order.setContract(contract); |
| | | order.setSize(size); |
| | | order.setPrice("0"); |
| | | order.setTif(FuturesOrder.TifEnum.IOC); |
| | | order.setReduceOnly(true); |
| | | order.setText("t-grid-mkt-close"); |
| | | FuturesOrder result = futuresApi.createFuturesOrder(SETTLE, order, null); |
| | | log.info("[TradeExec] 市价止盈成功, 价格:{}, size:{}, id:{}", result.getFillPrice(), size, result.getId()); |
| | | } catch (Exception e) { |
| | | log.error("[TradeExec] 市价止盈也失败, size:{}", size, e); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 异步清除指定合约的所有止盈止损条件单。 |
| | | */ |
| | | public void cancelAllPriceTriggeredOrders() { |
| | |
| | | |
| | | log.info("========== Gate K线数据 =========="); |
| | | log.info("名称: {} 时间: {}", data.getString("n"), DateUtil.TimeStampToDateTime(data.getLong("t"))); |
| | | log.info("开盘: {} 最高: {} 最低: {} 收盘: {} 成交量: {} 成交额: {} 已完结: {}", |
| | | data.getString("o"), data.getString("h"), data.getString("l"), |
| | | data.getString("c"), data.getString("v"), data.getString("a"), |
| | | data.getBooleanValue("w")); |
| | | log.info("收盘: {} 已完结: {}",data.getString("c"),data.getBooleanValue("w")); |
| | | log.info("=================================="); |
| | | |
| | | if (gridTradeService != null) { |