The problem of transferring from MT4 to MT5. Or, more precisely, the inability to execute some algorithms in MT5 without'err. - page 10

 
Vict:

It's strange, but I didn't think of doing it before:

It would get rid of some mass of error checks, like memory allocation.

not an option, the EA will be removed from the chart, and you only need to "exit to OS" before the next tick from any place in the program


Most likely, it is possible to elegantly wrap everything in a macro, to safely call functions related to the unavailability of data on the current tick, here is a "dummy"

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);
  }
//+------------------------------------------------------------------+

for code readability it would be nice to just write it that way:

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


Is this Try realistically wrapped in a macro and "exit to OS" in case of failure?

 
Igor Makanu:

is it realistic to wrap this Try into a macro and "exit to OS" in case of failure?

#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");

No?

I often write all sorts of minimaxes right at the beginning of a function, with undefine at the end. Naturally, if action is repeated often, otherwise it makes no sense.

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

And you're wrong about abortion, it's perfect with some errors.

 
Vict:

No?

Yes!

but ideally I'd like it instead:

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

like this:

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

it's not a question of making the Open() function signature different... But in this form I'll get what I'd really like! ;)

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

PS: as an option even globally described variables Tryerror or bool Tryresult would do - the purpose of one line "safe call", if this call ended with an error exit from body OnTick()

 
Igor Makanu:

like this:

I doubt it's possible, even in the pluses (you can throw in an exception, but it's unlikely). But stuff happens, maybe someone will surprise ...

 

So, at a quick glance:

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

that's probably the maximum in this situation.

 

Totally dumb, you can do it, can't you?

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");

I haven't compiled it, but it should work.

 
Vict:

I'm so stupid, I can't help it, can I?

I did not compile it, but it should work.

Shaitan the machine!!! It worked!!!

checked and simulated error ( 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


Awesome! And the macro code turned out to be really simple


THANK YOU! - You are definitely a magician!)

 

Please feel free to use it.

Macro above has one disadvantage - helper's type is hardcoded, you cannot pass to Try function returning string and then double without creating two macros. I got a sporting interest - how to get around it (to write one macro for all types. In µl without options, in c++, although it's not really needed there, but still)? No one is willing to suggest their own variant (well, you have to keep yourself in shape, after all)?

 
Vict:

You are welcome to use it.

The macro above has one disadvantage - the helper type is hardwired, you can't pass a function returning string into Try

Why not? The + sign has never been cancelled!

this is how I've combed out your macro, and how I plan to use it:

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 ");

now the macro parameterEXCEPT is an exception action, works fine as return or just ; - if you decide to unprint to log, but don't leave body 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:

Well, I mean, it's like this:

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;
}

People here don't seem to be gambling. Oh, come on.

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;                                         \
   }