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

 
Vict:

这很奇怪,但我以前没有想过要这样做。

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

不是一个选项,EA将被从图表中删除,你只需要在程序的任何地方在下一个tick之前 "退出操作系统"。


最有可能的是,它可以优雅地把所有东西都包在一个宏里,安全地调用与当前tick上的数据不可用有关的函数,这里有一个 "假的"

void OnStart()
  {
   for(int i=0;i<10;i++)
     {
      double o=Open(i);
      if(o>0.0) printf("%d : %f",i,o);
      else
        {
         printf("Error № %d ",(int)o);
         return;
        }
     }
  }
//+------------------------------------------------------------------+

double Open(int shift)
  {
   ResetLastError();
   double result=iOpen(NULL,0,shift);
   int err=GetLastError();
   if(err>0) result=-err;
   return(result);
  }
//+------------------------------------------------------------------+

为了代码的可读性,直接这样写就好了。

void OnStart()
  {
   for(int i=0;i<10;i++)
     {
      double o=Try( Open(i),"Текст сообщения" );
      printf("%d : %f",i,o);
     }
  }


这个Try现实地被包裹在一个宏中,并且在失败的情况下 "退出操作系统 "吗?

 
Igor Makanu:

把这个Try包在一个宏里,在失败的情况下 "退出操作系统",这是否现实?

#define  Try(VAR, EXPR, MES)          \
   VAR = EXPR;                       \
   if (VAR <= 0.0) {                 \
     printf("Error: %s ", MES);      \
     return;                         \
   }

double o;
Try(o, Open(i), "something goes wrong");

不是吗?

我经常在一个函数的开头写各种最小值,最后写undefine。自然,如果行动经常重复,否则就没有意义了。

#define  MYERR_HANDLER(INDEX)                                \
{                                                           \
   Alert(__FILE__, " ", __LINE__, "-", INDEX, ": error");   \
   this.state = obst_error;                                 \
   return obev_no_event;                                    \
}

而且你对堕胎的看法是错误的,对于某些错误,它是完美的。

 
Vict:

不是吗?

是的!

但在理想情况下,我反而喜欢它。

double o;
Try(o, Open(i), "something goes wrong");

像这样。

double o = Try(Open(i), "something goes wrong");

这不是一个使Open()函数签名不同的问题......但在这种形式下,我将得到我真正想要的东西!;)

----------------------

PS:作为一种选择,即使是全局描述的变量 Tryerror或bool Tryresult也能做到--目的是单行 "安全调用",如果该调用以错误结束,则从主体OnTick()退出。

 
Igor Makanu:

像这样。

我怀疑这是否可能,即使是正数(你可以抛出一个例外,但这不太可能)。但事情发生了,也许有人会感到惊讶......。

 

因此,一目了然。

Try(double, o, Open(i), "something goes wrong");

这可能是这种情况下的最大限度。

 

完全是哑巴,你能做到的,不是吗?

double Try_helper;
#define  Try(EXPR, MES)               \
   Try_helper = EXPR;                \
   if (Try_helper <= 0.0) {          \
     printf("Error: %s ", MES);      \
     return;                         \
   }

double o = Try(Open(i), "something goes wrong");

我还没有编译它,但它应该可以工作。

 
Vict:

我是如此愚蠢,我不能帮助它,是吗?

我没有编译它,但它应该可以工作。

它成功了!!!。

检查和模拟错误( shift>5 )

double Try_helper;
#define  Try(EXPR, MES)               \
   Try_helper = EXPR;                \
   if (Try_helper <= 0.0) {          \
     printf("Error: %s ", MES);      \
     return;                         \
   }

void OnStart()
  {
   for(int i=0;i<10;i++)
     {
      
      double o = Try(Open(i), "something goes wrong");
      printf("%d : %f",i,o);
     }
  }
//+------------------------------------------------------------------+

double Open(int shift)
  {
   ResetLastError();
   double result=iOpen(NULL,0,shift);
   int err=GetLastError()>0;
   if(err>0) result=-err;
   if(shift>5) result = -999;
   return(result);
  }
//+------------------------------------------------------------------+

2019.07.31 16:58:48.154 tst1 (EURUSD,H1) 0 : 1.115010

2019.07.31 16:58:48.154 tst1 (EURUSD,H1) 1 : 1.114670

2019.07.31 16:58:48.154 tst1 (EURUSD,H1) 2 : 1.114590

2019.07.31 16:58:48.154 tst1 (EURUSD,H1) 3 : 1.114400

2019.07.31 16:58:48.154 tst1 (EURUSD,H1) 4 : 1.115240

2019.07.31 16:58:48.154 tst1 (EURUSD,H1) 5 : 1.115450

2019.07.31 16:58:48.154 tst1 (EURUSD,H1) Error: something goes wrong


棒极了!而且宏的代码原来真的很简单


谢谢你!- 你绝对是个魔术师!)

 

请自由使用。

上面的宏有一个缺点--helper的类型是硬编码的,你不能在不创建两个宏的情况下把返回字符串和双倍数的函数传给Try。我有一个运动的兴趣--如何绕过它(为所有类型写一个宏。在没有选项的µl中,在c++中,虽然那里并不真正需要,但仍然)?没有人愿意提出自己的变体(好吧,毕竟你要保持自己的身材)?

 
Vict:

欢迎你使用它。

上面的宏有一个缺点--帮助器类型是硬性规定的,你不能把一个返回字符串的函数传入Try

为什么不呢?"+"号从来没有被取消过。

这就是我梳理你的宏的方式,以及我打算如何使用它。

int    _GetLastError;
double _Try_helper;
string _Try_FUNCSIG;
#define  Try(FUNC,MSG, EXCEPT) _Try_helper=FUNC;if(_GetLastError>0){printf("%s : error № %d %s ",_Try_FUNCSIG,_GetLastError,MSG);EXCEPT;}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   for(int i=0;i<10;i++)
     {

      double o = Try(Open(i), "something goes wrong"+Txt(),return);
      printf("%d : %f",i,o);
     }
  }
//+------------------------------------------------------------------+

double Open(int shift)
  {
   _Try_FUNCSIG=__FUNCSIG__;
   ResetLastError();
   double result=iOpen(NULL,0,shift);
   _GetLastError=GetLastError();
   if(shift>5)_GetLastError=999;
   return(result);
  }
//+------------------------------------------------------------------+
string Txt()
{
return(" Txt ");

现在,宏参数EXCEPT是一个异常动作,如果你决定取消打印到日志中,则可以作为返回或只是;--如果你决定取消打印到日志中,但不要留下正文OnTick()。

2019.07.31 19:01:28.353 tst1 (EURUSD,H1) 0 : 1.113350

2019.07.31 19:01:28.353 tst1 (EURUSD,H1) 1 : 1.114180

2019.07.31 19:01:28.353 tst1 (EURUSD,H1) 2 : 1.115110

2019.07.31 19:01:28.353 tst1 (EURUSD,H1) 3 : 1.115010

2019.07.31 19:01:28.353 tst1 (EURUSD,H1) 4 : 1.114670

2019.07.31 19:01:28.353 tst1 (EURUSD,H1) 5 : 1.114590

2019.07.31 19:01:28.353 tst1 (EURUSD,H1) double Open(int) : error #999 something goes wrong Txt

 
Igor Makanu:

嗯,我的意思是,它是这样的。

string f(int) {return "hello world";}
double f(double) {return 35;}

int main()
{
   double d = Try(f(0.), "double error");
   string s = Try(f(0), "stirng error");
   cout << s << "-" << d << endl;  // hello world-35
   return 0;
}

这里的人似乎并不赌博。哦,来吧。

template <typename T> T Try_helper;
#define  Try(EXPR, MES)                                  \
   Try_helper<decltype(EXPR)> = EXPR;                   \
   if (Try_helper<decltype(EXPR)> == decltype(EXPR){}) {\
      printf("%s\n", MES);                              \
      return 1;                                         \
   }