从MT4转移到MT5的问题。或者,更确切地说,在MT5中无法执行某些算法而不出现错误。 - 页 9

 
Vict:

是的,有异常的代码要简单得多,也干净得多,持续的错误检查会把它变成一团糟。但在µl中存在很多问题,没有例外。 开发商没有拉横幅。

在我看来,这没有什么区别。

对于返回代码--你需要写一个类似RETURN_IF_BAD_RESULT()的宏,并把它贴在所有返回结果的函数中。

除了例外情况--你需要写TRY-CACTH部分。另外,你必须记住哪些函数会抛出异常,哪些不会,在你的代码中添加注释//异常。

有些东西是小菜一碟,有些则是...

 
Vict:

是的,有异常的代码要简单得多,也干净得多,不断地检查错误会使它变成一个纠结的混乱。但在µl中存在很多问题,没有例外。 开发商无法拉动十字架。

不,我甚至没有说到例外情况......另外,可能有一个 "邪恶的鞋匠"......谁将把所有在阵列 之外的旅行变成例外))))

我认为,你只需要一种方法,将所有的返回与退出分解成OS......让它成为一些Exit(),你的想法是对的,我不想增加无尽的代码线轴--总是将所有的函数调用包裹在其中是没有意义的。

void OnStart()
{
if(!MyFuncReadOHLC_1()) return;
if(!MyFuncReadOHLC_2()) return;
....
}
 
Georgiy Merts:

在我看来,这没有什么区别。

对于返回代码--你需要写一个类似RETURN_IF_BAD_RESULT()的宏,并把它贴在所有返回结果的函数中。

除了例外情况--你需要写TRY-CACTH部分。另外--记住哪些函数会抛出异常,哪些不会,在你的代码中添加注释//异常。

有些东西很乱,有些东西很乱......。

对于例外情况,我不需要记住任何东西,往往连TRY-CACTH也不需要(只是会终止程序崩溃),这是一种例外情况,通常不会发生,不要把它们变成if-else块。例如--我写了一个类似向量的东西(pathetic-like),而不是在分配不成功的时候抛出异常,我不得不去搞运营商!并在每次插入的时候把它拉出来(虽然我已经忘记了),好处可疑。

 
Igor Makanu:

我认为,你只需要能够用操作系统打破一切......

是的,这也可以,奇怪的是,它不在那里......

 
Vict:

是的,也没有什么,奇怪的是,它不存在......。

我只是不放心把有可读代码的短程序变成某种怪物,这里是MQL4的一个典型模板--检查 "新栏",检查指标--与订单一起工作或不工作。

void OnTick()
  {
   int takeprofit,stoploss; 
   double lot;
   ENUM_CMD CMD1,CMD2,CMD3;
   CMD1 = ind1();
   CMD2 = ind2();
   CMD3 = ind3();
   if(NewBar())
     {
      DeleteOrdersLimits(Magic);
      if(CMD1==CMD_BUY && CMD2==CMD_BUY && CMD3==CMD_BUY)
        {
         CalcTakeProfitStopLoss(takeprofit,stoploss);
         lot=CalcLot(stoploss);
         if(ReversSignal)SELL_STOP_PR(Low[1],lot,Magic,stoploss,takeprofit); else BUY_STOP_PR(High[1],lot,Magic,stoploss,takeprofit);
        }
      if(CMD1==CMD_SELL && CMD2==CMD_SELL && CMD3==CMD_SELL)
        {
         CalcTakeProfitStopLoss(takeprofit,stoploss);
         lot=CalcLot(stoploss);
         if(ReversSignal)BUY_STOP_PR(High[1],lot,Magic,stoploss,takeprofit);else SELL_STOP_PR(Low[1],lot,Magic,stoploss,takeprofit);
        }
     }
  }
//+------------------------------------------------------------------+

在这个例子中,指标 "拉动每一个刻度",因为它们在不同的TFs上工作...这并不重要。

我在ind1()、ind2()、ind3()和NewBar() 使用OHLC数据。

如果我在一次函数调用 中得到一个时间序列访问错误,继续执行这段代码的意义何在?- 我需要退出操作系统并等待新的刻度,即在任何ind1(),ind2(),ind3()和NewBar(),我检查GetLastError()并在收到错误时立即退出操作系统并在EA日志中写入

 
Vict:

对于例外情况,我不需要记住任何东西,往往连TRY-CACTH都不需要(程序在紧急情况下会直接终止),这是一种例外情况,一般不会发生,不要把它们变成if-else块。例如--我写了一个类似向量的东西(pathetic-like),而不是在分配不成功的时候抛出异常,我不得不去搞运营商!并在每次插入的时候把它拉出来(虽然我已经忘记了),好处可疑。

嗯,来吧,伙计...

你说,"你不需要记住任何东西",然后你继续说:很多时候甚至不需要TRY-CATCH,这个同样的 "很多时候 "意味着某个地方需要块,某个地方不需要,你需要记住它。 这种情况和返回码是一样的--如果你请求某些资源而发生异常(返回错误),资源必须被拒绝。也就是说,在任何情况下,你都必须记住哪个函数会抛出异常,哪个不会。

哦,关于 "特殊情况"...。嗯,我怎么能说...没有引号似乎是抛出一个例外的合理理由,但这是一个 "例外情况 "吗?

 
Igor Makanu:

我只是不放心把有可读代码的短程序变成某种怪物,这里是MQL4的一个典型模板--检查 "新栏",检查指标--与订单一起工作或不工作。

在这个例子中,指标 "拉动每一个刻度",因为它们在不同的TFs上工作...这并不重要。

我在ind1()、ind2()、ind3()和NewBar() 使用OHLC数据。

如果我在一次函数调用 中得到一个时间序列访问错误,继续执行这段代码的意义何在?- 我需要退出操作系统并等待新的刻度,即在任何ind1(),ind2(),ind3()和NewBar(),我检查GetLastError(),得到错误后立即退出操作系统并在EA日志中记录

调用return(iErrrCode)有什么问题?

 
Georgiy Merts:

调用return(iErrrCode)的问题是什么?

嗯,我将尝试在代码中显示出来,我重写了代码,如果OHLC数据处理不正确,就会有退出,它看起来像这样。

void OnTick()
  {
   int takeprofit,stoploss; 
   double lot;
   bool nb;
   ENUM_CMD CMD1,CMD2,CMD3;
   if(!ind1( CMD1 )) return;
   if(!ind2( CMD2 )) return;
   if(!ind3( CMD3 )) return;
   if(!NewBar( nb )) return;
   
   if( nb )
     {
      DeleteOrdersLimits(Magic);
      if(CMD1==CMD_BUY && CMD2==CMD_BUY && CMD3==CMD_BUY)
        {
         CalcTakeProfitStopLoss(takeprofit,stoploss);
         lot=CalcLot(stoploss);
         if(ReversSignal)SELL_STOP_PR(Low[1],lot,Magic,stoploss,takeprofit); else BUY_STOP_PR(High[1],lot,Magic,stoploss,takeprofit);
        }
      if(CMD1==CMD_SELL && CMD2==CMD_SELL && CMD3==CMD_SELL)
        {
         CalcTakeProfitStopLoss(takeprofit,stoploss);
         lot=CalcLot(stoploss);
         if(ReversSignal)BUY_STOP_PR(High[1],lot,Magic,stoploss,takeprofit);else SELL_STOP_PR(Low[1],lot,Magic,stoploss,takeprofit);
        }
     }
  }

现在我通过引用获得函数值,如果函数处理不正确则退出(在讨论的背景下--终端没有通过 TF准备历史数据)。

 
Georgiy Merts:

嗯,来吧,伙计...

你说,"你不需要记住任何东西",然后你继续说:很多时候甚至不需要TRY-CATCH,这个同样的 "很多时候 "意味着某个地方需要块,某个地方不需要,你需要记住它。 这种情况和返回码是一样的--如果你请求某些资源而发生异常(返回错误),资源必须被拒绝。也就是说,在任何情况下,你都必须记住哪个函数会抛出异常,哪个不会。

哦,关于 "特殊情况"...。嗯,我怎么能说...没有引号是一个合理的事情,可以抛出一个例外,但这是一个 "例外情况 "吗?

你莫名其妙地以你自己的方式使用了例外,显然是错误的。一般来说,你不应该去管这个函数是否抛出异常。拥有TRY-CATCH是可选的。而为了避免资源问题,让RAIIhttps://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D0%B5_%D1%80%D0%B5%D1%81%D1%83%D1%80%D1%81%D0%B0_%D0%B5%D1%81%D1%82%D1%8C_%D0%B8%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F, 旋转堆栈会把它全部清理掉。

而关于 "特殊情况"...嗯,我怎么说呢...缺乏引文似乎是抛出一个例外的合理借口,但这是一个 "例外情况 "吗?
排他性由代码作者决定,但例外情况当然不应该与if-else相类似。
 

奇怪的是,我以前并没有想到这一点。

// Немедленное завершение, деструкторы не вызываются
void abort() {Alert(1/(uint)MathAbs(0));}

它摆脱了一些大量的错误检查,如内存分配

原因: