MT4 EA 课程:ATR 止损和头寸规模

 

欢迎来到我们的 MetaTrader4 Expert Advisor 课程的第五部分!如果您还没有这样做,请查看前几期。

我们的专家顾问一直做得很好。我们创建了一个功能齐全的 EA,它可以发出买卖订单,也可以追踪我们的止损。然而,到目前为止,我们一直使用 50 点的固定止损。

这通常没问题,但如果您想要动态止损怎么办?为了更好地反映市场动态,我们可以使用波动率指标,例如 ATR(平均真实范围)来确定我们的止损。

 

当我们使用动态止损距离时,我们仍然希望保持每笔交易的风险相同。我们使用动态调整头寸来做到这一点。换句话说,我们将更改每笔交易的手数以反映我们使用 1% 止损的愿望。让我们看看如何将其添加到我们的 Wall-E 专家顾问中!

 

基于 ATR 的动态止损

 

让我们刷新一下到目前为止我们一直在做的事情。到目前为止,我们总是创建 50 点(或 500 点)的止损,如下所示:

 

39
int stopLoss = 500;

 

这很好,但它没有考虑到市场的波动性。此外,如果我们想在 10 分钟图表上交易这个智能交易系统,它显然需要与我们在日线图上交易时不同的止损点。50 点绝对不是一刀切的价值。

 

我们可以通过使用 ATR 指标来解决这个问题。ATR 指标是一种技术分析指标,它向我们展示了市场在特定时期内的波动性。它不显示市场的方向,只是该市场是否波动。它使用价格变动范围来确定这一点。

 

MT4 EA 课程:ATR 止损和头寸规模

我们如何使用这个 ATR 指标?我们将创建一个止损距离,该距离是该 ATR 值的倍数。这样,当市场波动较大时,我们的止损将更大,而当市场正在盘整时,它将使用更严格的止损。我们可以这样做:

 

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// Here, we fetch the current 3-period ATR value
double atr = iATR(NULL, 0, 3, 0);
// Since the stop loss will be a multiple of this ATR value,
// we define this multiple. 2.5 times the ATR value
// is often a good start:
double atrMultiple = 2.5;
// Now, we set our stop loss.
// We multiply the ATR value by the ATR multiple
// and divide by the Point constant
// in order to get a value in points:
int stopLoss = (int)(atr * atrMultiple / Point);
// And, since we have a dynamic stop loss value,
// it makes sense to use the same pips amount as our take profit
int takeProfit = stopLoss;

 

我们去吧。请记住,我们仍然使用 0.01 的固定手数。快速回测向我们展示了有希望的结果:

 

MT4 EA 课程:ATR 止损和头寸规模

 

但是,如您所见,在总共进行了近 250 笔交易后,我们以 10,000 美元开始,仅以 10,166 美元结束。这并没有错,但这显然仍然反映了我们正在使用的小批量。让我们看看如何改变这一点,以便每笔交易承担 1% 的风险。

动态仓位调整

 

我们刚刚设法使我们的止损动态化,但由于这一点以及我们使用固定手数的事实,我们每笔交易冒着不同金额的风险。这并不理想,因为我们更愿意在每笔交易中承担相同百分比的风险。

 

假设我们每笔交易的风险应该是 1%。如果我们有一个 1,000 美元的交易账户,每笔交易将只是 1,000 美元的 1%,因此如果价格触及我们的止损,我们每笔交易的风险为 10 美元。低风险止损是可靠交易策略的标志之一,这听起来不错,但我们如何在代码中实现这一点?

 

calculateLotSize 函数

 

我们需要更改的第一件事是添加一个名为calculateLotSize()的新函数。我们可以将其添加到我们的专家顾问文件的底部:

 

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/**
* Calculate the amount of lots needed based on stop loss
*
* @return double
*/
double calculateLotSize(int stopLoss)
{
    // 1% risk per trade
    int risk = 1;
    
    // Fetch some symbol properties
    double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
    double minLot  = MarketInfo(Symbol(), MODE_MINLOT);
    double maxLot  = MarketInfo(Symbol(), MODE_MAXLOT);
    double tickVal = MarketInfo(Symbol(), MODE_TICKVALUE);
    // Calculate the actual lot size
    double lotSize = AccountBalance() * risk / 100 / (stopLoss * tickVal);
    return MathMin(
        maxLot,
        MathMax(
            minLot,
            NormalizeDouble(lotSize / lotStep, 0) * lotStep // This rounds the lotSize to the nearest lotstep interval
        )
    );
}

 

由于这是本章代码中最复杂的部分,让我们一个一个地过一遍。首先,我们定义每笔交易的风险应该是多少,在我们的例子中是 1%。该风险变量将在几行之后用于手数计算。

 

101
int risk = 1;

 

接下来,我们将获取当前交易品种的一些属性,以计算我们的手数应该是多少。这里最重要的是tickVal,它保存了该交易品种单个刻度的价格。然后,我们计算实际手数。为了做到这一点,我们获取账户余额,取该余额的 1%,这样我们就有了我们想要承担的最大风险金额。然后,我们将此值除以我们的止损价格以获得手数:

 

103
104
105
106
107
108
109
110
// Fetch some symbol properties
double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
double minLot  = MarketInfo(Symbol(), MODE_MINLOT);
double maxLot  = MarketInfo(Symbol(), MODE_MAXLOT);
double tickVal = MarketInfo(Symbol(), MODE_TICKVALUE);
// Calculate the actual lot size
double lotSize = AccountBalance() * risk / 100 / (stopLoss * tickVal);

 

最后,我们使用最小手数和最大手数限制,因此我们不会尝试打开太大或太小的订单并将手数值四舍五入到最近的手数步长。这将是一个有用的例子,例如在 DAX 上,最小手数是 0.1,然后是 0.2、0.3 等。最后一步确保我们不使用像 0.05、0.13 等这样的手数值,我们的经纪人不会接受的。

 

112
113
114
115
116
117
118
return MathMin(
    maxLot,
    MathMax(
        minLot,
        NormalizeDouble(lotSize / lotStep, 0) * lotStep // This rounds the lotSize to the nearest lotstep interval
    )
);

 

使用动态手数

现在我们有了手数计算功能,我们只需要更新一段代码,我们在其中定义了手数。请记住,它看起来像这样:

 

38
double lots = 0.01;

 

我们将更新这一行,因此它使用我们的新手数函数而不是固定手数:

 

38
double lots = calculateLotSize(stopLoss);

 

只需确保您已经定义了stopLoss变量,这意味着您可能需要将上述行移动到止损计算下方几行。但就是这样,我们已经完成了所有需要的更改,以便实现基于 ATR 的动态止损和动态手数,以便始终使用每笔交易 1% 的风险!

结论

现在我们已经实现了一切,让我们再看看我们的权益图:

MT4 EA 课程:ATR 止损和头寸规模

 

如您所见,在相同的 250 次交易期间,我们现在能够将最初的 10,000 美元余额增加到更好的 12,586 美元!这些是我们可以开始为之自豪的利润!另请注意,净值图底部添加了一个新面板,指示手数如何变化,具体取决于我们所持仓位。

我们的专家顾问正在取得越来越好的结果!让我们回顾一下我们在本章中所做的事情:

  • 我们已经认识到,为了适应市场不断变化的波动,最好使用动态止损
  • 我们使用了 ATR 指标的倍数作为包含这种波动性的动态止损值
  • 我们了解了为什么我们应该使用动态头寸规模:保持每笔交易的风险相等,无论我们的止损距离如何
  • 我们使用新的 calculateLotSize() 函数实现了动态头寸调整,也就是动态手数调整

发表回复

后才能评论