feat: 最大阈值波段百分比、是否开启移动止损

This commit is contained in:
zhangyangbin
2026-05-17 07:33:13 +08:00
parent 9538444713
commit 7aa785cc0c
2 changed files with 72 additions and 16 deletions
+21 -9
View File
@@ -14,12 +14,14 @@
input group "=== 波段识别参数 ==="
input ENUM_TIMEFRAMES InpTimeframe = PERIOD_M1; // K线周期
input int InpMAPeriod = 14; // MA周期
input double InpWavePercent = 0.1; // 波段阈值百分比(%)
input double InpMinWavePercent = 0.1; // 最小波段阈值百分比(%)
input double InpMaxWavePercent = 1.0; // 最大波段阈值百分比(%)
input double InpPullbackTolerance = 0.0; // 反向突破容忍度(%) 0=不容忍
input group "=== 风险管理参数 ==="
input double InpStopLossPercent = 0.05; // 止损百分比(%)
input double InpRiskRewardRatio = 1.5; // 盈亏比
input bool InpUseTrailingStop = true; // 使用移动止损
input int InpMaxHoldingMinutes = 5; // 最大持仓时间(分钟)
input group "=== 仓位管理参数 ==="
@@ -102,12 +104,13 @@ int OnInit()
Print("品种:", _Symbol);
Print("K线周期:", EnumToString(InpTimeframe));
Print("MA周期:", InpMAPeriod);
Print("波段阈值: ", InpWavePercent, "%");
Print("波段阈值范围: ", InpMinWavePercent, "% - ", InpMaxWavePercent, "%");
if(InpPullbackTolerance > 0)
Print("反向突破容忍度: ", DoubleToString(InpPullbackTolerance, 1), "% (启用)");
else
Print("反向突破容忍度: 0% (禁用 - 保持原有逻辑)");
Print("止损:", InpStopLossPercent, "% | 盈亏比:", InpRiskRewardRatio);
Print("止损:", InpStopLossPercent, "% (最小1美元) | 盈亏比:", InpRiskRewardRatio);
Print("移动止损:", (InpUseTrailingStop ? "启用" : "禁用"));
Print("最大持仓时间:", InpMaxHoldingMinutes, "分钟");
Print("最大开仓手数:", InpMaxPositions);
Print("手数模式:", (InpUseCompounding ? "复利" : "固定"),
@@ -354,9 +357,11 @@ void UpdateLatestValidWave()
// 计算阈值(百分比模式:以前一个极值点价格为基准计算百分比)
double base_price = extremes[i-1].price;
double threshold = (base_price * InpWavePercent / 100.0) / _Point;
double min_threshold = (base_price * InpMinWavePercent / 100.0) / _Point;
double max_threshold = (base_price * InpMaxWavePercent / 100.0) / _Point;
if(price_diff_points >= threshold) {
// 波段必须在最小和最大阈值之间才是有效波段
if(price_diff_points >= min_threshold && price_diff_points <= max_threshold) {
extremes[i-1].is_valid = true;
extremes[i].is_valid = true;
}
@@ -374,9 +379,11 @@ void UpdateLatestValidWave()
// 计算阈值(百分比模式)
double base_price = extremes[i-1].price;
double threshold = (base_price * InpWavePercent / 100.0) / _Point;
double min_threshold = (base_price * InpMinWavePercent / 100.0) / _Point;
double max_threshold = (base_price * InpMaxWavePercent / 100.0) / _Point;
if(price_diff_points >= threshold) {
// 波段必须在最小和最大阈值之间才是有效波段
if(price_diff_points >= min_threshold && price_diff_points <= max_threshold) {
// 找到最新的有效波段
double high = MathMax(extremes[i].price, extremes[i-1].price);
double low = MathMin(extremes[i].price, extremes[i-1].price);
@@ -405,7 +412,8 @@ void UpdateLatestValidWave()
Print("更新最新有效波段 - 高:", DoubleToString(high, _Digits),
" 低:", DoubleToString(low, _Digits),
" 价差:", (int)price_diff_points, "点",
" 阈值:", StringFormat("%.2f%% (%.0f点)", InpWavePercent, threshold));
" 阈值范围:", StringFormat("%.2f%%-%.2f%% (%.0f-%.0f点)",
InpMinWavePercent, InpMaxWavePercent, min_threshold, max_threshold));
}
}
break;
@@ -559,7 +567,7 @@ void CheckOpenSignals()
// 计算当前波段的实际阈值(百分比模式:取高低点的平均值作为基准)
double base_price = (latest_wave.high_price + latest_wave.low_price) / 2.0;
double wave_threshold_points = (base_price * InpWavePercent / 100.0) / _Point;
double wave_threshold_points = (base_price * InpMinWavePercent / 100.0) / _Point;
// 检查多单信号:突破高点(且该高点未使用过)
if(!latest_wave.high_used && current_price > latest_wave.high_price) {
@@ -715,6 +723,10 @@ void ManagePositions()
//+------------------------------------------------------------------+
void CheckTrailingStop(ulong ticket)
{
// 如果未开启移动止损,直接返回
if(!InpUseTrailingStop)
return;
if(!PositionSelectByTicket(ticket))
return;
+51 -7
View File
@@ -27,12 +27,15 @@
### 波段识别参数
- K线周期:支持参数设置,不跟随图表,默认 **1 Minute**
- MA周期:默认 **14**
- 波段阈值百分比:默认 **0.1%**
- **最小波段阈值百分比:默认 0.1%**(波段必须 >= 此值才可能是有效波段)
- **最大波段阈值百分比:默认 1.0%**(波段必须 <= 此值才可能是有效波段)
- **有效波段范围:0.1% - 1.0%**(只交易此范围内的波段)
- **反向突破容忍度:默认0.0%(新功能 - 详见下方说明)**
### 风险管理参数
- 止损百分比:默认 **0.05%**(基于开仓价计算,最小1美元/100点)
- 盈亏比:默认 **1.5**(止盈 = 止损金额 × 盈亏比)
- 使用移动止损:默认 **true**(启用移动止损功能)
- 最大持仓时间:默认 **5分钟**
### 仓位管理参数
@@ -89,12 +92,41 @@
3. 建议先回测不同容忍度,找到最适合的数值
4. 容忍度只影响波段识别,不影响止损止盈等其他逻辑
### 波段阈值说明
本策略使用**百分比模式**计算波段阈值
- 以前一个极值点价格为基准,按百分比计算阈值
### 波段阈值范围说明
本策略使用**波段范围筛选**机制,只交易特定大小的波段
#### 为什么需要波段范围?
- **单一阈值的问题**:传统策略只设置最小阈值(如0.1%),导致0.1%的小波段和5%的大波段都交易,风险收益特征差异巨大
- **范围筛选的优势**:通过设置最小和最大阈值,只交易特定大小的波段,风险更可控
#### 计算方式
- 以前一个极值点价格为基准,按百分比计算阈值范围
- 动态适应不同价格水平
- 例如:设置0.1%,价格2600时阈值为2.6美元(260点),价格4700时阈值为4.7美元(470点)
- 百分比模式能够根据价格水平自动调整,更好地适应市场变化
#### 示例说明
假设设置:
- 最小阈值:0.1%
- 最大阈值:1.0%
- 当前价格:2600
**价格2600时的阈值范围:**
- 最小阈值 = 2600 × 0.1% = 2.6美元(260点)
- 最大阈值 = 2600 × 1.0% = 26美元(2600点)
**波段筛选结果:**
- 波段 2.0美元(200点):< 最小阈值 → ❌ 不交易(波段太小)
- 波段 5.2美元(520点):在范围内 → ✅ 有效波段,可交易
- 波段 15美元(1500点):在范围内 → ✅ 有效波段,可交易
- 波段 30美元(3000点):> 最大阈值 → ❌ 不交易(波段太大)
**价格4700时的阈值范围:**
- 最小阈值 = 4700 × 0.1% = 4.7美元(470点)
- 最大阈值 = 4700 × 1.0% = 47美元(4700点)
#### 参数调整建议
- **保守型**0.15% - 0.5%(只交易中小波段)
- **标准型**0.1% - 1.0%(默认,覆盖大多数波段)
- **激进型**0.08% - 2.0%(交易范围更广)
### 止损止盈说明
本策略使用**百分比模式**计算止损和止盈:
@@ -115,6 +147,18 @@
- 多单止盈价 = 1500 + 1.5 = 1501.5
- 空单止盈价 = 1500 - 1.5 = 1498.5
- **移动止损**:当浮盈达到止损金额时,自动将止损移至成本价(开仓价)
- **移动止损**(可选功能,默认启用):
- **触发条件**:当浮盈 >= 止损金额时触发
- **移动目标**:将止损移至成本价(开仓价)
- **移动次数**:仅移动一次(保本策略)
- **示例**:开仓价2603.24,止损金额1.30美元
- 当价格涨至2604.54(浮盈1.30)时,止损从2601.94移至2603.24
- 之后价格无论涨到多高,止损都保持在2603.24
- 即使回调至成本价,也能保本离场,不会亏损
- **开关控制**:可通过参数"使用移动止损"关闭此功能
- **最小止损保护**:无论百分比设置多小,止损金额始终不低于1美元(100点),避免止损过小导致频繁触发
- **移动止损的作用**
- ✅ 启用时:浮盈达标后锁定盈亏平衡,避免盈利单变亏损
- ❌ 禁用时:止损始终保持在初始位置,追求更高止盈,但风险更大