Administrator
2026-08-12 31085bebba69a02104078ee7414ad928638b9380
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package com.xcong.excoin.modules.gateApi;
 
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
 
import java.math.BigDecimal;
 
/**
 * 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();
    }
}