| | |
| | | import lombok.NoArgsConstructor; |
| | | |
| | | import java.math.BigDecimal; |
| | | import java.util.LinkedHashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * Gate 策略配置 DTO,用于 Web 控制面板参数传递。 |
| | |
| | | private int maxPositionSize; |
| | | /** 止损阶梯次数,0=禁用 */ |
| | | private int stopLossCount; |
| | | /** 止盈网格跨度:相邻止盈单跨越的网格数量,默认 2 */ |
| | | private int takeProfitGridSpan; |
| | | /** 策略重启跨度阈值,0=禁用 */ |
| | | private int restartGridSpan; |
| | | /** 价格精度 */ |
| | |
| | | private String unrealizedPnlPriceMode; |
| | | /** 是否为生产环境 */ |
| | | private boolean isProduction; |
| | | /** 价格驱动开关:true=启用K线推送中的价格驱动逻辑,false=禁用。null=未设置(默认true) */ |
| | | private Boolean priceDriveEnabled; |
| | | /** 策略运行轮数上限:达到盈利后重启计数,达到此值后不再重启。0=不限 */ |
| | | private int rounds; |
| | | /** 止损次数统计方式:"single"=单向分别统计 / "dual"=双向统一统计,默认 "dual" */ |
| | | private String stopLossCountMode; |
| | | /** 加仓间隔:每隔多少次止损触发一次加仓,默认 3 */ |
| | | private int addPositionInterval; |
| | | /** 加仓数量:每次加仓追加的张数,默认 1 */ |
| | | private int addPositionQuantity; |
| | | /** 单边最大仓位量:单向持仓张数上限,超出则按上限挂单,0=不限制 */ |
| | | private int maxPositionPerSide; |
| | | /** 加仓启动阈值:前N次止损不触发加仓,默认 1 */ |
| | | private int addPositionStartThreshold; |
| | | /** 超额止盈开关:true=挂单成交后将超出基础仓位的部分挂止盈单,默认 false */ |
| | | private boolean placeExcessTakeProfit; |
| | | |
| | | /** |
| | | * 从 GateConfig 构建 DTO(不暴露 apiSecret)。 |
| | |
| | | .quantity(config.getQuantity()) |
| | | .maxPositionSize(config.getMaxPositionSize()) |
| | | .stopLossCount(config.getStopLossCount()) |
| | | .takeProfitGridSpan(config.getTakeProfitGridSpan()) |
| | | .restartGridSpan(config.getRestartGridSpan()) |
| | | .priceScale(config.getPriceScale()) |
| | | .contractMultiplier(config.getContractMultiplier()) |
| | | .unrealizedPnlPriceMode(config.getUnrealizedPnlPriceMode() != null |
| | | ? config.getUnrealizedPnlPriceMode().name() : "LAST_PRICE") |
| | | .isProduction(config.isProduction()) |
| | | .priceDriveEnabled(config.isPriceDriveEnabled()) |
| | | .rounds(config.getRounds()) |
| | | .stopLossCountMode(config.getStopLossCountMode()) |
| | | .addPositionInterval(config.getAddPositionInterval()) |
| | | .addPositionQuantity(config.getAddPositionQuantity()) |
| | | .maxPositionPerSide(config.getMaxPositionPerSide()) |
| | | .addPositionStartThreshold(config.getAddPositionStartThreshold()) |
| | | .placeExcessTakeProfit(config.isPlaceExcessTakeProfit()) |
| | | .build(); |
| | | } |
| | | |
| | | /** |
| | | * 所有可调参数的扁平快照 — stats 埋点 + STRATEGY_START payload 用。 |
| | | * 新增参数只需在此方法加一行,无需修改 stats 消费者。 |
| | | */ |
| | | public Map<String, Object> toParamsMap() { |
| | | Map<String, Object> m = new LinkedHashMap<>(); |
| | | m.put("contract", contract); |
| | | m.put("leverage", leverage); |
| | | m.put("gridRate", gridRate); |
| | | m.put("expectedProfit", expectedProfit); |
| | | m.put("maxLoss", maxLoss); |
| | | m.put("baseQuantity", baseQuantity); |
| | | m.put("quantity", quantity); |
| | | m.put("maxPositionSize", maxPositionSize); |
| | | m.put("stopLossCount", stopLossCount); |
| | | m.put("takeProfitGridSpan", takeProfitGridSpan); |
| | | m.put("priceDriveEnabled", priceDriveEnabled); |
| | | m.put("rounds", rounds); |
| | | m.put("stopLossCountMode", stopLossCountMode); |
| | | m.put("addPositionInterval", addPositionInterval); |
| | | m.put("addPositionQuantity", addPositionQuantity); |
| | | m.put("maxPositionPerSide", maxPositionPerSide); |
| | | m.put("addPositionStartThreshold", addPositionStartThreshold); |
| | | m.put("placeExcessTakeProfit", placeExcessTakeProfit); |
| | | return m; |
| | | } |
| | | |
| | | /** |
| | | * 带默认值的工厂方法 — 统一 Manager 和 HTML 的默认值入口。 |
| | | */ |
| | | public static GateConfigDTO defaultsFor(String apiKey) { |
| | | return GateConfigDTO.builder() |
| | | .apiKey(apiKey) |
| | | .contract("ETH_USDT") |
| | | .leverage("100") |
| | | .marginMode("cross") |
| | | .positionMode("dual") |
| | | .gridRate(new BigDecimal("0.005")) |
| | | .expectedProfit(new BigDecimal("0.15")) |
| | | .maxLoss(new BigDecimal("1.5")) |
| | | .baseQuantity("2") |
| | | .quantity("2") |
| | | .maxPositionSize(4) |
| | | .stopLossCount(0) |
| | | .takeProfitGridSpan(2) |
| | | .restartGridSpan(0) |
| | | .priceScale(1) |
| | | .contractMultiplier(new BigDecimal("0.001")) |
| | | .unrealizedPnlPriceMode("LAST_PRICE") |
| | | .isProduction(true) |
| | | .priceDriveEnabled(true) |
| | | .rounds(0) |
| | | .stopLossCountMode("dual") |
| | | .addPositionInterval(3) |
| | | .addPositionQuantity(1) |
| | | .maxPositionPerSide(0) |
| | | .addPositionStartThreshold(1) |
| | | .placeExcessTakeProfit(false) |
| | | .build(); |
| | | } |
| | | } |