| | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.math.RoundingMode; |
| | | |
| | | /** |
| | | * 止损管理器 — 负责基底止损单挂载、止损触发后的逐步缩进、以及止损追挂。 |
| | |
| | | |
| | | private final OkxConfig config; |
| | | private final OkxTradeExecutor executor; |
| | | |
| | | /** 多仓挂单张数计数器:止损触发时递增后再使用;挂单成交后重置为1 */ |
| | | private volatile int longEntryQty = 1; |
| | | /** 空仓挂单张数计数器:止损触发时递增后再使用;挂单成交后重置为1 */ |
| | | private volatile int shortEntryQty = 1; |
| | | |
| | | public StopLossManager(OkxConfig config, OkxTradeExecutor executor) { |
| | | this.config = config; |
| | |
| | | } |
| | | |
| | | BigDecimal triggerPrice = newEntryGrid.getGridPrice(); |
| | | BigDecimal priceDiff = longEntryPrice.subtract(triggerPrice).abs(); |
| | | BigDecimal epsilon = new BigDecimal("0.00000001"); |
| | | int count = priceDiff.add(epsilon).divide(config.getStep(), 0, RoundingMode.DOWN).intValue(); |
| | | count = Math.max(1, count); |
| | | int entryQty = count * Integer.parseInt(config.getQuantity()); |
| | | longEntryQty++; |
| | | int entryQty = longEntryQty * Integer.parseInt(config.getQuantity()); |
| | | String size = String.valueOf(entryQty); |
| | | log.info("[OKX] 多仓止损触发 gridId:{}, 在gridId:{}挂{}张多单(价差:{},步长:{},count:{},qty:{})", |
| | | gridId, newEntryGridId, entryQty, priceDiff, config.getStep(), count, config.getQuantity()); |
| | | log.info("[OKX] 多仓止损触发 gridId:{}, 在gridId:{}挂{}张多单(计数器:{}, qty:{})", |
| | | gridId, newEntryGridId, entryQty, longEntryQty, config.getQuantity()); |
| | | newEntryGrid.getLongTraderParam().setQuantity(size); |
| | | placeEntryOrderWithPreFlag(newEntryGrid, true, triggerPrice, size); |
| | | } |
| | |
| | | } |
| | | |
| | | BigDecimal triggerPrice = newEntryGrid.getGridPrice(); |
| | | BigDecimal priceDiff = shortEntryPrice.subtract(triggerPrice).abs(); |
| | | BigDecimal epsilon = new BigDecimal("0.00000001"); |
| | | int count = priceDiff.add(epsilon).divide(config.getStep(), 0, RoundingMode.DOWN).intValue(); |
| | | count = Math.max(1, count); |
| | | int entryQty = count * Integer.parseInt(config.getQuantity()); |
| | | shortEntryQty++; |
| | | int entryQty = shortEntryQty * Integer.parseInt(config.getQuantity()); |
| | | String size = String.valueOf(entryQty); |
| | | log.info("[OKX] 空仓止损触发 gridId:{}, 在gridId:{}挂{}张空单(价差:{},步长:{},count:{},qty:{})", |
| | | gridId, newEntryGridId, entryQty, priceDiff, config.getStep(), count, config.getQuantity()); |
| | | log.info("[OKX] 空仓止损触发 gridId:{}, 在gridId:{}挂{}张空单(计数器:{}, qty:{})", |
| | | gridId, newEntryGridId, entryQty, shortEntryQty, config.getQuantity()); |
| | | newEntryGrid.getShortTraderParam().setQuantity(size); |
| | | placeEntryOrderWithPreFlag(newEntryGrid, false, triggerPrice, size); |
| | | } |
| | |
| | | gridElement.setShortTakeProfitOrderId(profitId); |
| | | OkxGridElement.refreshIndices(); |
| | | } |
| | | |
| | | // ========== 计数器管理 ========== |
| | | |
| | | /** 重置多仓挂单张数计数器(挂单成交后调用) */ |
| | | public void resetLongEntryQty() { longEntryQty = 1; } |
| | | |
| | | /** 重置空仓挂单张数计数器(挂单成交后调用) */ |
| | | public void resetShortEntryQty() { shortEntryQty = 1; } |
| | | |
| | | /** 重置全部挂单张数计数器(startGrid时调用) */ |
| | | public void resetAllEntryQuantities() { longEntryQty = 1; shortEntryQty = 1; } |
| | | } |