| | |
| | | private String longTakeProfitOrderId; |
| | | /** 空仓止盈订单 ID */ |
| | | private String shortTakeProfitOrderId; |
| | | /** 多仓止损订单 ID */ |
| | | private String longStopLossOrderId; |
| | | /** 空仓止损订单 ID */ |
| | | private String shortStopLossOrderId; |
| | | /** 多仓止损订单 ID 列表(支持一个网格多个止损单) */ |
| | | private List<String> longStopLossOrderIds = new ArrayList<>(); |
| | | /** 空仓止损订单 ID 列表(支持一个网格多个止损单) */ |
| | | private List<String> shortStopLossOrderIds = new ArrayList<>(); |
| | | |
| | | /** 索引重建锁,保证 refreshIndices() 与计数读取之间互斥,避免 clear→rebuild 窗口期读到 0 */ |
| | | private static final Object INDEX_LOCK = new Object(); |
| | | |
| | | /** 全局 ID 索引,由 {@link GateConfig#setGridElements(List)} 触发重建,O(1) 查找 */ |
| | | private static final Map<Integer, GridElement> INDEX = new ConcurrentHashMap<>(); |
| | |
| | | return SHORT_TP_ORDER_ID_INDEX.get(orderId); |
| | | } |
| | | |
| | | /** @return 当前多仓止盈单数量 */ |
| | | public static int getLongTakeProfitCount() { return LONG_TP_ORDER_ID_INDEX.size(); } |
| | | /** @return 当前多仓止盈单数量(与 refreshIndices 互斥,避免清空窗口读到 0) */ |
| | | public static int getLongTakeProfitCount() { |
| | | synchronized (INDEX_LOCK) { return LONG_TP_ORDER_ID_INDEX.size(); } |
| | | } |
| | | |
| | | /** @return 当前空仓止盈单数量 */ |
| | | public static int getShortTakeProfitCount() { return SHORT_TP_ORDER_ID_INDEX.size(); } |
| | | /** @return 当前空仓止盈单数量(与 refreshIndices 互斥,避免清空窗口读到 0) */ |
| | | public static int getShortTakeProfitCount() { |
| | | synchronized (INDEX_LOCK) { return SHORT_TP_ORDER_ID_INDEX.size(); } |
| | | } |
| | | |
| | | /** |
| | | * 根据多仓止损订单 ID 快速查找网格元素(O(1))。 |
| | |
| | | * 使快速查找方法获取到最新数据。 |
| | | */ |
| | | public static void refreshIndices() { |
| | | PRICE_INDEX.clear(); |
| | | LONG_ORDER_ID_INDEX.clear(); |
| | | SHORT_ORDER_ID_INDEX.clear(); |
| | | LONG_TP_ORDER_ID_INDEX.clear(); |
| | | SHORT_TP_ORDER_ID_INDEX.clear(); |
| | | LONG_SL_ORDER_ID_INDEX.clear(); |
| | | SHORT_SL_ORDER_ID_INDEX.clear(); |
| | | for (GridElement e : INDEX.values()) { |
| | | putDynamicIndices(e); |
| | | synchronized (INDEX_LOCK) { |
| | | PRICE_INDEX.clear(); |
| | | LONG_ORDER_ID_INDEX.clear(); |
| | | SHORT_ORDER_ID_INDEX.clear(); |
| | | LONG_TP_ORDER_ID_INDEX.clear(); |
| | | SHORT_TP_ORDER_ID_INDEX.clear(); |
| | | LONG_SL_ORDER_ID_INDEX.clear(); |
| | | SHORT_SL_ORDER_ID_INDEX.clear(); |
| | | for (GridElement e : INDEX.values()) { |
| | | putDynamicIndices(e); |
| | | } |
| | | } |
| | | // logAll 在锁外执行,不阻塞计数查询 |
| | | logAll(); |
| | | } |
| | | |
| | |
| | | StringBuilder sb = new StringBuilder("\n========== 网格数据 ==========\n"); |
| | | for (GridElement e : sorted) { |
| | | if (e.isHasLongOrder() || e.isHasShortOrder() |
| | | || e.getLongStopLossOrderId() != null || e.getShortStopLossOrderId() != null){ |
| | | || e.hasLongStopLossOrders() || e.hasShortStopLossOrders()){ |
| | | sb.append(String.format( |
| | | " ID=%4d 价格=%s up=%s down=%s 多仓=%s(%s) 空仓=%s(%s) 多止盈=%s 空止盈=%s 多止损=%s 空止损=%s\n", |
| | | e.getId(), |
| | |
| | | e.getShortOrderId() != null ? e.getShortOrderId() : "-", |
| | | e.getLongTakeProfitOrderId() != null ? e.getLongTakeProfitOrderId() : "-", |
| | | e.getShortTakeProfitOrderId() != null ? e.getShortTakeProfitOrderId() : "-", |
| | | e.getLongStopLossOrderId() != null ? e.getLongStopLossOrderId() : "-", |
| | | e.getShortStopLossOrderId() != null ? e.getShortStopLossOrderId() : "-" |
| | | e.hasLongStopLossOrders() ? String.join(",", e.getLongStopLossOrderIds()) : "-", |
| | | e.hasShortStopLossOrders() ? String.join(",", e.getShortStopLossOrderIds()) : "-" |
| | | )); |
| | | } |
| | | } |
| | |
| | | if (e.getShortTakeProfitOrderId() != null) { |
| | | SHORT_TP_ORDER_ID_INDEX.put(e.getShortTakeProfitOrderId(), e); |
| | | } |
| | | if (e.getLongStopLossOrderId() != null) { |
| | | LONG_SL_ORDER_ID_INDEX.put(e.getLongStopLossOrderId(), e); |
| | | for (String slId : e.getLongStopLossOrderIds()) { |
| | | LONG_SL_ORDER_ID_INDEX.put(slId, e); |
| | | } |
| | | if (e.getShortStopLossOrderId() != null) { |
| | | SHORT_SL_ORDER_ID_INDEX.put(e.getShortStopLossOrderId(), e); |
| | | for (String slId : e.getShortStopLossOrderIds()) { |
| | | SHORT_SL_ORDER_ID_INDEX.put(slId, e); |
| | | } |
| | | } |
| | | |
| | |
| | | this.shortOrderId = builder.shortOrderId; |
| | | this.longTakeProfitOrderId = builder.longTakeProfitOrderId; |
| | | this.shortTakeProfitOrderId = builder.shortTakeProfitOrderId; |
| | | this.longStopLossOrderId = builder.longStopLossOrderId; |
| | | this.shortStopLossOrderId = builder.shortStopLossOrderId; |
| | | if (builder.longStopLossOrderIds != null) this.longStopLossOrderIds.addAll(builder.longStopLossOrderIds); |
| | | if (builder.shortStopLossOrderIds != null) this.shortStopLossOrderIds.addAll(builder.shortStopLossOrderIds); |
| | | } |
| | | |
| | | // ==================== 网格层级编号 ==================== |
| | |
| | | |
| | | // ==================== 多仓止损订单 ID ==================== |
| | | |
| | | /** @return 多仓止损订单 ID */ |
| | | public String getLongStopLossOrderId() { return longStopLossOrderId; } |
| | | /** 设置多仓止损订单 ID */ |
| | | public void setLongStopLossOrderId(String longStopLossOrderId) { this.longStopLossOrderId = longStopLossOrderId; } |
| | | // ==================== 多仓止损订单 ID 列表 ==================== |
| | | |
| | | // ==================== 空仓止损订单 ID ==================== |
| | | /** @return 多仓止损订单 ID 列表 */ |
| | | public List<String> getLongStopLossOrderIds() { return longStopLossOrderIds; } |
| | | /** 添加一个多仓止损订单 ID */ |
| | | public void addLongStopLossOrderId(String orderId) { longStopLossOrderIds.add(orderId); } |
| | | /** 移除一个多仓止损订单 ID */ |
| | | public boolean removeLongStopLossOrderId(String orderId) { return longStopLossOrderIds.remove(orderId); } |
| | | /** 清空所有多仓止损订单 ID */ |
| | | public void clearLongStopLossOrderIds() { longStopLossOrderIds.clear(); } |
| | | /** @return 是否有止损单 */ |
| | | public boolean hasLongStopLossOrders() { return !longStopLossOrderIds.isEmpty(); } |
| | | |
| | | /** @return 空仓止损订单 ID */ |
| | | public String getShortStopLossOrderId() { return shortStopLossOrderId; } |
| | | /** 设置空仓止损订单 ID */ |
| | | public void setShortStopLossOrderId(String shortStopLossOrderId) { this.shortStopLossOrderId = shortStopLossOrderId; } |
| | | // ==================== 空仓止损订单 ID 列表 ==================== |
| | | |
| | | /** @return 空仓止损订单 ID 列表 */ |
| | | public List<String> getShortStopLossOrderIds() { return shortStopLossOrderIds; } |
| | | /** 添加一个空仓止损订单 ID */ |
| | | public void addShortStopLossOrderId(String orderId) { shortStopLossOrderIds.add(orderId); } |
| | | /** 移除一个空仓止损订单 ID */ |
| | | public boolean removeShortStopLossOrderId(String orderId) { return shortStopLossOrderIds.remove(orderId); } |
| | | /** 清空所有空仓止损订单 ID */ |
| | | public void clearShortStopLossOrderIds() { shortStopLossOrderIds.clear(); } |
| | | /** @return 是否有止损单 */ |
| | | public boolean hasShortStopLossOrders() { return !shortStopLossOrderIds.isEmpty(); } |
| | | |
| | | public static Builder builder() { |
| | | return new Builder(); |
| | |
| | | private String longTakeProfitOrderId; |
| | | /** 空仓止盈订单 ID */ |
| | | private String shortTakeProfitOrderId; |
| | | /** 多仓止损订单 ID */ |
| | | private String longStopLossOrderId; |
| | | /** 空仓止损订单 ID */ |
| | | private String shortStopLossOrderId; |
| | | /** 多仓止损订单 ID 列表 */ |
| | | private List<String> longStopLossOrderIds; |
| | | /** 空仓止损订单 ID 列表 */ |
| | | private List<String> shortStopLossOrderIds; |
| | | |
| | | /** 设置网格层级编号 */ |
| | | public Builder id(int id) { this.id = id; return this; } |
| | |
| | | public Builder longTakeProfitOrderId(String longTakeProfitOrderId) { this.longTakeProfitOrderId = longTakeProfitOrderId; return this; } |
| | | /** 设置空仓止盈订单 ID */ |
| | | public Builder shortTakeProfitOrderId(String shortTakeProfitOrderId) { this.shortTakeProfitOrderId = shortTakeProfitOrderId; return this; } |
| | | /** 设置多仓止损订单 ID */ |
| | | public Builder longStopLossOrderId(String longStopLossOrderId) { this.longStopLossOrderId = longStopLossOrderId; return this; } |
| | | /** 设置空仓止损订单 ID */ |
| | | public Builder shortStopLossOrderId(String shortStopLossOrderId) { this.shortStopLossOrderId = shortStopLossOrderId; return this; } |
| | | /** 设置多仓止损订单 ID 列表 */ |
| | | public Builder longStopLossOrderIds(List<String> longStopLossOrderIds) { this.longStopLossOrderIds = longStopLossOrderIds; return this; } |
| | | /** 设置空仓止损订单 ID 列表 */ |
| | | public Builder shortStopLossOrderIds(List<String> shortStopLossOrderIds) { this.shortStopLossOrderIds = shortStopLossOrderIds; return this; } |
| | | |
| | | public GridElement build() { |
| | | return new GridElement(this); |