需要帮助来发现一些轻微的错误。 - 页 2

 
有谁愿意伸出援手,请.....。
 

问题的一部分是你写代码的方式,长长的if条件中充满了&&、||和一个又一个的函数调用,这使得它很难调试,你会很幸运地发现有人有时间来解开这一团乱麻。你应该看看文档中的编码例子,看看代码应该如何用更短的行来格式化并加以注释。

 

":( 虽然从未听说过这些,但这是真的吗....?

编译器也很难对我的代码进行调试 :( ?

如果是这个原因的话,意味着我不得不重新考虑我对这部分的所有编码想法。那么它将变成一个完全不同的东西...... :( :(

 

是的,它很难调试,例如,看看这个跟踪止损的代码。它很容易看到每一行的作用,因此很容易发现错误。

   int total=OrdersTotal();
   
   for(int cnt=0; cnt<total; cnt++)
   {if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
    {if(OrderType()==OP_BUY)
     {if(TrailingStop>0)
      {if(Bid-OrderOpenPrice()>Point*TrailingStop)
       {if(OrderStopLoss()<Bid-Point*TrailingStop)
        {if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
         {Print("OrderModify error ",GetLastError());
          return;
   }}}}}}}
 
我试着去掉&&条件,把它们作为一个if语句放在....。但还是不能一直工作,有时它只是移动了一次止损,有时对买入和卖出订单 都能正常工作。
 
SDC: 是的,这很难调试,例如,看看这段跟踪止损的代码。它很容易看到每一行的作用,因此很容易发现错误
   int total=OrdersTotal();
   
   for(int cnt=0; cnt<total; cnt++)
   {if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
    {if(OrderType()==OP_BUY)
     {if(TrailingStop>0)
      {if(Bid-OrderOpenPrice()>Point*TrailingStop)
       {if(OrderStopLoss()<Bid-Point*TrailingStop)
        {if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
         {Print("OrderModify error ",GetLastError());
          return;
   }}}}}}}
  1. 在有多个订单的情况下,你必须在关闭/删除时进行倒计时。想想其他图表上的EA。养成这个习惯。
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       {if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
        {if(OrderType()==OP_BUY)
         {if(TrailingStop>0)
          {if(Bid-OrderOpenPrice()>Point*TrailingStop)
           {if(OrderStopLoss()<Bid-Point*TrailingStop)
            {if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
             {Print("OrderModify error ",GetLastError());
              return;
       }}}}}}}
    也喜欢++x而不是x++(特别是在处理类的时候)。
  2. 语言是for() 语句,if() 语句,所以在单个语句周围加上大括号意义不大。
    你不会写

    { i = 1 + 2; }
    { if(i == 3) { Print(i); } }
    i = 1 + 2;
    if(i == 3) Print(i);
    所以简化了
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
       if(OrderType()==OP_BUY)
       if(TrailingStop>0)
       if(Bid-OrderOpenPrice()>Point*TrailingStop)
       if(OrderStopLoss()<Bid-Point*TrailingStop)
       if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
       {  Print("OrderModify error ",GetLastError());
          return;
       }
  3. 现在"&&"(和"||")是短路运算符,不要连锁ifs
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(!OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
       && OrderType()==OP_BUY)
       && TrailingStop>0)
       && Bid-OrderOpenPrice()>Point*TrailingStop)
       && OrderStopLoss()<Bid-Point*TrailingStop)
       && !OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
       {  Print("OrderModify error ",GetLastError());
          return;
       }
  4. 当顺序选择失败 时,你想修改顺序吗?
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(O rderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
       && OrderType()==OP_BUY)
       && TrailingStop>0)
       && Bid-OrderOpenPrice()>Point*TrailingStop)
       && OrderStopLoss()<Bid-Point*TrailingStop)
       && !OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
       {  Print("OrderModify error ",GetLastError());
          return;
       }
  5. 把所有不改变的测试从循环中移除。
    if TrailingStop>0){
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
       && OrderType()==OP_BUY)
       && Bid-OrderOpenPrice()>Point*TrailingStop)
       && OrderStopLoss()<Bid-Point*TrailingStop)
       && !OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green))
       {  Print("OrderModify error ",GetLastError());
          return;
       }
    }
  6. 不要一直计算同样的事情
       if(Bid-OrderOpenPrice()>Point*TrailingStop)
       if(OrderStopLoss()<Bid-Point*TrailingStop)
       if(!OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,O...
    弄清楚你想做什么,是否应该
    if TrailingStop>0){
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES))  
       && OrderType()==OP_BUY){
          double SL = Bid - Point*TrailingStop;
          if(SL > OrderOpenPrice()    // Start trailing above open price
          && SL > OrderStopLoss()     // And it moves up ONLY
          && !OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0,Green))
          {  Print("OrderModify error ",GetLastError());
             return;
          }
       }
    }
  7. 其他情况呢? 其他图表和EA 怎么办?
    if TrailingStop>0){
       for(int cnt=OrdersTotal() - 1; cnt >= 0; --cnt)
       if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES)
       && OrderMagicNumber() == MyExternal
       && OrderSymbol()      == Symbol()  
       ){  
          if(OrderType()==OP_BUY)
          {
             double SL = Bid - Point*TrailingStop;
             if(SL > OrderOpenPrice()    // Start trailing above open price
             && SL > OrderStopLoss()     // And it moves up ONLY
             && !OrderModify(OrderTicket(),OrderOpenPrice(),SL,OrderTakeProfit(),0,Green))
             {  Print("OrderModify error ",GetLastError());
                return;
             }
          }  // OP_BUY
          else // OP_SELL (or pending)
          { ...                       
          }                           
       }  // OrderSelect
    }  // Trailing

 
WHRoeder:
  1. 在有多个订单的情况下,关闭/删除时必须倒数。想想其他图表上的EA。养成这个习惯。另外,更喜欢++x而不是x++(特别是在处理类的时候)。
  2. 语言是for() 语句,if() 语句,所以在单个语句周围加括号意义不大。
    你不会写
    但是
    所以要简化
  3. 现在"&&"(和"||")是短路操作符,不要将ifs 连在一起。
  4. 当顺序选择失败 后,你想修改顺序吗?
  5. 把所有不改变的测试从循环中移除。
  6. 不要一直计算同样的事情。弄清楚你想做什么,是否应该这样做
  7. 其他情况呢? 其他图表和EA 怎么办?

我发布这段代码只是作为一个易于阅读的代码的例子,它并不意味着是一个完整的独立功能的例子。

它是MetaQuotes MACD样本EA中的追踪止损代码的买单部分,包含在MT4中。

1)不对,你可以向上或向下计数,循环更有效,OrdersTotal()被调用一次,并分配给一个本地var。

 
SDC: 我贴出的代码只是作为一个例子o
我贴的只是一个放大的主题。
 

谢谢你,SDC。也谢谢你的提示,WHRoeder。这很有用。

我试着把OrderClosePrice()换成之前代码中的MarketInfo,并进行了编辑(去掉&&条件,把它们作为一个if语句放在后面,即第二个for循环中的那个),但结果仍然是有时工作有时不工作。

在计算池中的总订单的for循环中,我使用了倒数循环,但有x--。我不明白你为什么建议--x。

我在谷歌上搜索了 "短路运算符",但不太明白它在mql4的意思,你介意解释一下吗^_^?为什么链式 "if "不好?

顺便说一下,上面SDC建议的代码,这不是我使用的代码>.<。

 

将ifs连锁起来并不坏。MQL4语言的开发者写了我上面发布的代码。这是我从他们的macd样本EA中剪切出来的一些代码,作为一个例子。

WHR指的是最近对&&|条件评估方式的改变,现在使它们与连锁的if条件同样有效。以前,它们的效率较低。你可以使用两种方法。当代码中存在分歧时,链式ifs很有用,因此你可以使用 "else"。

长行的if(&&||)条件会造成括号的混乱,使查找错误更加困难,这就是为什么我不喜欢这样做。另外,有一个公认的编码标准,说它不应该超过80个字符宽。但是,很多编码者不愿意遵守这个标准,而且MQL4的开发者一直在创建大长名字的枚举标识符,用于他们的函数调用 同样大长名字的函数,这对代码的格式化没有很大的帮助。