package com.xcong.excoin.modules.gateApi;
|
|
import lombok.AllArgsConstructor;
|
import lombok.Builder;
|
import lombok.Data;
|
import lombok.NoArgsConstructor;
|
|
import java.math.BigDecimal;
|
import java.util.LinkedHashMap;
|
import java.util.Map;
|
|
/**
|
* Gate 策略配置 DTO,用于 Web 控制面板参数传递。
|
* apiSecret 不暴露给前端。
|
*/
|
@Data
|
@Builder
|
@NoArgsConstructor
|
@AllArgsConstructor
|
public class GateConfigDTO {
|
|
/** API Key */
|
private String apiKey;
|
/** 合约名称,如 ETH_USDT */
|
private String contract;
|
/** 杠杆倍数 */
|
private String leverage;
|
/** 保证金模式:cross / isolated */
|
private String marginMode;
|
/** 持仓模式:single / dual */
|
private String positionMode;
|
/** 网格间距比例 */
|
private BigDecimal gridRate;
|
/** 预期收益(USDT) */
|
private BigDecimal expectedProfit;
|
/** 最大亏损(USDT) */
|
private BigDecimal maxLoss;
|
/** 基底开仓张数 */
|
private String baseQuantity;
|
/** 每次下单张数 */
|
private String quantity;
|
/** 最大持仓张数(单方向),0=不限制 */
|
private int maxPositionSize;
|
/** 止损阶梯次数,0=禁用 */
|
private int stopLossCount;
|
/** 止盈网格跨度:相邻止盈单跨越的网格数量,默认 2 */
|
private int takeProfitGridSpan;
|
/** 策略重启跨度阈值,0=禁用 */
|
private int restartGridSpan;
|
/** 价格精度 */
|
private int priceScale;
|
/** 合约乘数 */
|
private BigDecimal contractMultiplier;
|
/** 未实现盈亏计价模式:LAST_PRICE / MARK_PRICE */
|
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)。
|
*/
|
public static GateConfigDTO from(GateConfig config) {
|
return GateConfigDTO.builder()
|
.apiKey(config.getApiKey())
|
.contract(config.getContract())
|
.leverage(config.getLeverage())
|
.marginMode(config.getMarginMode())
|
.positionMode(config.getPositionMode())
|
.gridRate(config.getGridRate())
|
.expectedProfit(config.getExpectedProfit())
|
.maxLoss(config.getMaxLoss())
|
.baseQuantity(config.getBaseQuantity())
|
.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(false)
|
.priceDriveEnabled(true)
|
.rounds(0)
|
.stopLossCountMode("dual")
|
.addPositionInterval(3)
|
.addPositionQuantity(1)
|
.maxPositionPerSide(0)
|
.addPositionStartThreshold(1)
|
.placeExcessTakeProfit(false)
|
.build();
|
}
|
}
|