5.3 移动停损
我们也可以用交易单回路修改多张交易单。移动停损就是常见的例子。移动停损会随着交易单获利而以交易单价格上下移动停损。移动停损可"锁定"获利,并提供绝佳的损失保障。
移动停损以最大点数表示。例如,移动停损若设为50 点,则你的停损永远会在价格的50 点内。如价格反转,获利下降,停损就留在原地。停损仅往获利的方向移动,不会反向移动。
修改移动停损时,须查看目前市价和停损价的点差是否大于移动停损。若是,停损就会被修改,这样距离目前市价的点差才会等于移动停损的点差。
移动停损依平仓价来计算,平仓价就是买单的买价或卖单的卖价。请注意:平仓价与入单价正好相反。
我们来检查修改移动停损的代码。首先,我们声明移动停损设定的外部变量:

以下的源代码会检查所有市价买单,并在必要时修改停损:

以OrderSelect ( )选择交易单库后,用目前的买价减去停损设定,再乘以PipPoint ( ),来确定最大移动停损间距。此间距会储存在变量Max Stoploss 中。
我们用MQL 功能NormalizeDouble ( )将MaxStopLoss 变量舍入至正确的小数字数。MetaTrader 的报价最高可达8 位小数位。透过使用NormalizeDouble ( ) ,我们将报价舍入至4 位或5 位小数(日元报价为2 -3 位小数) 。
接着,获取目前选定的交易单的停损,并用NormalizeDouble( )舍入,以保证策略安全。我们指定此值给变量CurrentStop 。
然后查看目前的交易单是否需要修改。如自定义数字、符号及交易单类型都符合,而且目前的停损( CurrentStop) 小于MaxStopLoss ,就修改交易单的停损。我们把MaxStopLoss 变量当作新的停损传送至OrderModify ( )功能。
如OrderMod均( )功能不成功,就会执行错误处理程序,而且目前价格信息、单号、目前停损及修改停损都会打印至日志中。
卖单的移动停损条件不同,须个别讨论。这里是修改卖单的条件:

请注意条件( CurrentStop > MaxStopLoss//CurrentStop == 0) 。若下单时未设停损,则条件CurrentStop> MaxStopLoss 永远不会成立,因为MaxStopLoss 永远不会小于零。因此,我们加入Or 条件, CurrentStop ==0 。
5.3.1 最低获利
我们透过设定最低获利价位来加强移动停损。在上述的例子中,移动停损会立即生效。如设初始停损100 点,移动停损50 点,则停损会立即设为50 点,使你初始设置的100点停损变成无效。
加设最低获利价位就能设定初始停损,同时延后移动停损,直到指定获利额达成。在此例中,我们假设下单时已设定初始停损100点。我们使用移动停损50 点以及最低获利价位50 点。交易单获利达到点时,停损将调整至损益平衡。
我们为最低获利设定一个外部变量:

下面的功能为所有市价买单修改了停损,运行前请先检查最低获利:


我们以目前买价减去OrderOpenPrice ( )计算目前的交易单获利点数,并把它储存在变量PipsProfit 中。比较交易单获利点数和最低获利设定,后者是乘以PipPoint( )并储存在变量MinProfit 中。
如目前的获利点数( PipsProfit )大于或等于最低获利( MinPorfit) ,而所有其他条件都成立,就会修改停损。
有最低获利设定的移动停损就灵活多了,你可能会想在expert advisor 中用此功能。完整的卖出移动停损代码请见附录D 。
5.3.2 损益平衡停损(Break Even Stop)
你也可用此方法为交易单申请损益平衡停损调整。损益平衡停损是在一定的获利价位达成后,将停损调整至等于入单价。损益平衡停损是独立的,不受你的初始停损和移动停损功能影响。
以下为损益平衡获利设定的外部变量,其有指定最低获利点数:

交易单获利点一旦大于等于BreakEvenProfit (损益平衡获利) ,此代码就会把所有市价买单的停损改成损益平衡。我们不会为此建立功能,若觉得有用你可以这样做。

我们用"目前的买价-入单价"来计算目前的获利点数,并把它储存在PipsProfit 中。我们计算最低获利点数,并储存到MinProfit 中。如果PipsProfit 大于等于MinProfit ,我们就会把停损价改成入单价。
我们还会检查,以确保停损不是设在损益平衡价。如果OrderOpenPrice ( )不等于OrderStopLoss ( ) ,我们就可继续进行。