feat: 最大阈值波段百分比、是否开启移动止损
This commit is contained in:
@@ -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
@@ -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点),避免止损过小导致频繁触发
|
||||
|
||||
- **移动止损的作用**:
|
||||
- ✅ 启用时:浮盈达标后锁定盈亏平衡,避免盈利单变亏损
|
||||
- ❌ 禁用时:止损始终保持在初始位置,追求更高止盈,但风险更大
|
||||
|
||||
Reference in New Issue
Block a user