可能有许多不同类型的追踪止损可能性,但出于我们的目的,我们将研究最有效的:追踪止损将在自定义阈值后激活,然后按自定义点数水平追踪。 在订单价格首次达到利润阈值后,此追踪止损会随着订单价格向上或向下移动止损。 在这篇 MQL4 Trailing Stop 文章中了解如何使用追踪止损锁定利润并提供损失保护来为您的 Expert Advisor 编程。
例如,如果您将利润阈值设置为 50 并将追踪止损设置为 50,则在激活追踪止损之前,交易必须移动 50 个利润点,此时止损将移动至收支平衡。 如果您进一步指出您的追踪步长是 5,那么在您的止损点高于盈亏平衡点 5 点之前,市场必须再上涨 5 个点。 然后它会在此基础上逐渐向上调整,每增加 5 点的收益就多锁定 5 点的利润。
因此,这个新的追踪止损需要三个外部变量,一个表示利润阈值,另一个表示追踪止损,最后一个表示步进距离:
外部双 TrailingStart = 50;
外部双 TrailingStop = 25;
外部双 TrailingStep = 5;
因此,用户操纵的变量是 TrailingStart,这是在可以激活追踪止损之前需要达到的利润阈值; TrailingStop,这是我们将从新的利润高点追踪的点数; 和 TrailingStep,在止损之前需要获得的新点数可以增加增益量。
让我们检查一下这个追踪止损的代码:
void TrailOrder(double Trailingstart,double Trailingstop){
国际票 = 0;
双 tStopLoss = NormalizeDouble(OrderStopLoss(), 数字); // 止损
int cnt,vPoint,vSlippage;
双 sl = OrderStopLoss(); // 止损
如果(数字 == 3 || 数字 == 5)
{vPoint = 点 * 10; vSlippage = 滑点 * 10; }
别的
{vPoint = 点; vSlippage = 滑点;}
刷新率();
如果(订单总数()> 0){
for(cnt=OrdersTotal();cnt>=0;cnt–){
OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
if(OrderType()<=OP_SELL && OrderSymbol()==Symbol()
&& OrderMagicNumber()==MagicNumber){
if(OrderType()==OP_BUY){
if(Ask> NormalizeDouble(OrderOpenPrice()+TrailingStart* vPoint,Digits)
&& tStopLoss < NormalizeDouble(Bid-(TrailingStop+TrailingStep)*vPoint,Digits)){
tStopLoss = NormalizeDouble(Bid-TrailingStop*vPoint,Digits);
ticket = OrderModify(OrderTicket(),OrderOpenPrice(),tStopLoss,OrderTakeProfit(),0,Blue);
如果(票 > 0){
打印(“TrailingStop #2 已激活:”,OrderSymbol(),“:SL”,tStopLoss,“:Bid”,Bid);
返回(0);
}}}
如果 (OrderType()==OP_SELL) {
if (Bid < NormalizeDouble(OrderOpenPrice()-TrailingStart*vPoint,Digits)
&& (sl >(NormalizeDouble(Ask+(TrailingStop+TrailingStep)*vPoint,Digits)))
|| (OrderStopLoss()==0)){
tStopLoss = NormalizeDouble(Ask+TrailingStop*vPoint,Digits);
ticket = OrderModify(OrderTicket(),OrderOpenPrice(),tStopLoss,OrderTakeProfit(),0,Red);
如果(票 > 0){
Print (“Trailing #2 Activated:”, OrderSymbol(), “: SL”,tStopLoss, “: Ask”, Ask);
返回(0);
}}}
}}}}
解释
我们使用 void TrailOrder() 作为我们的自定义函数。
您会注意到订单循环代码中的 for 循环和 OrderSelect() 函数。 它将遍历订单池并检查每个订单以查看我们是否需要对其应用追踪止损。 如果当前市价订单是买入市价订单,如 OP_BUY 所示,并且它与我们的图表符号和幻数相匹配,我们将继续进行追踪止损计算。
在激活两个追踪止损之前必须确定两个条件:
条件 1:检查 TrailingStart。 我们要求程序观察要价是否大于开盘价加上 TrailingStart 值。 例如,如果追踪开始设置为 50 点,那么追踪止损只能在市场盈利达到 50 点时激活。 在利润阈值之后激活追踪止损比在开始时更有意义。
条件 2:检查 TrailingStop 和 TrailingStep。 第二个条件检查当前止损是否小于当前价格减去追踪止损和追踪步长。 例如,如果追踪起点为 50 点,追踪止损为 25 点,追踪步进为 5 点,那么当交易获利移动 50 点时,条件 1 被激活,程序可以继续到条件 2,检查 TrailingStop 和 TrailingStep。 Condition2 然后确保将第一个止损调整为低于 50 点的利润阈值 25 点。 如果交易继续获利,则追踪止损将按定义的 TrailingStep 金额每增加 5 点再增加 5 点。
我们通过减去追踪止损设置,乘以 vPoint(),fr 来确定止损距离om 当前出价。 这存储在变量 tStopLoss 中。 我们将 tStopLoss 变量作为我们的新止损传递给 OrderModify() 函数。
注意:我们使用 MQL 函数 NormalizeDouble() 将我们的变量四舍五入到小数点后的正确位数。 报价最多可以保留八位小数,NormalizeDouble() 有助于将其四舍五入到 4 或 5 位数字(日元对为 2-3 位数字)。
我们在此处的代码中添加了一个打印功能,以便在我们的日志选项卡上打印出该追踪止损何时被激活的信息。
一般来说,卖单的追踪止损条件遵循与买单相同的逻辑。
那么现在,这个自定义函数如何插入到我们的 Start() 函数中,以便我们的代码知道我们正在使用它?
我们只需在 start() 函数内的任意位置放置一行,最好靠近函数的开头:
if(TrailingStop>0 && TrailingStart > 0) TrailOrder (TrailingStart, TrailingStop);
基本上,我正在创建一个条件 if 表达式来检查 TrailingStart 和 TrailingStop 是否都大于 0,也就是说,用户是否为这些字段定义了整数值。 如果是,那么自定义函数 TrailOrder() 将被激活。 否则,如果两个或其中一个字段保持默认值 0,则追踪止损保持停用状态。
这就是它的全部。 您现在拥有一个复杂的跟踪止损机制作为您武器库中的额外武器。