Das Problem der Umstellung von MT4 auf MT5. Oder, genauer gesagt, die Unfähigkeit, einige Algorithmen in MT5 ohne Fehler auszuführen. - Seite 10

 
Vict:

Es ist seltsam, aber daran habe ich vorher nicht gedacht:

Es würde eine Reihe von Fehlerprüfungen, wie z.B. die Speicherzuweisung, überflüssig machen.

keine Option, wird der EA aus dem Diagramm entfernt, und Sie müssen nur "exit to OS" vor dem nächsten Tick von jedem Ort im Programm


Höchstwahrscheinlich ist es möglich, alles elegant in ein Makro zu verpacken, um sicher Funktionen aufzurufen, die mit der Nichtverfügbarkeit von Daten zum aktuellen Tick zu tun haben, hier ein "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);
  }
//+------------------------------------------------------------------+

Für die Lesbarkeit des Codes wäre es schön, wenn man es einfach so schreiben könnte:

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


Ist dieser Versuch realistisch in einem Makro und "exit to OS" im Falle eines Fehlers verpackt?

 
Igor Makanu:

Ist es realistisch, diesen Versuch in ein Makro zu verpacken und im Falle eines Fehlers das Betriebssystem zu verlassen?

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

Nein?

Ich schreibe oft alle Arten von Minimaxen direkt am Anfang einer Funktion, mit undefine am Ende. Natürlich nur, wenn die Handlung oft wiederholt wird, sonst macht sie keinen Sinn.

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

Und du irrst dich, was die Abtreibung angeht, sie ist perfekt mit einigen Fehlern.

 
Vict:

Nein?

Ja!

aber idealerweise würde ich es stattdessen mögen:

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

wie diese:

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

es geht nicht darum, die Signatur der Open()-Funktion zu ändern... Aber in dieser Form werde ich bekommen, was ich wirklich möchte! ;)

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

PS: als Option würden auch global beschriebene Variablen Tryerror oder bool Tryresult genügen - der Zweck eines einzeiligen "sicheren Aufrufs", wenn dieser Aufruf mit einem Fehler endet, ist der Exit aus dem Body OnTick()

 
Igor Makanu:

wie diese:

Ich bezweifle, dass dies möglich ist, selbst bei den Pluszeichen (man kann eine Ausnahme machen, aber das ist unwahrscheinlich). Aber Dinge passieren, vielleicht wird jemand überrascht ...

 

Also, auf den ersten Blick:

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

das ist wahrscheinlich das Maximum in dieser Situation.

 

Völlig dumm, du kannst es doch, oder?

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

Ich habe es nicht kompiliert, aber es sollte funktionieren.

 
Vict:

Ich bin so dumm, ich kann nicht anders, oder?

Ich habe es nicht kompiliert, aber es sollte funktionieren.

Shaitan die Maschine!!! Es hat funktioniert!!!

geprüfter und simulierter Fehler ( 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) Fehler: etwas läuft schief


Und der Makrocode war wirklich einfach


DANKESCHÖN! - Sie sind wirklich ein Zauberer).

 

Sie können es gerne verwenden.

Das obige Makro hat einen Nachteil - der Typ des Helfers ist hart kodiert, man kann nicht an Try function returning string und dann double übergeben, ohne zwei Makros zu erstellen. Ich habe ein sportliches Interesse daran, wie man das umgehen kann (ein Makro für alle Typen zu schreiben). In µl ohne Optionen, in c++, obwohl es dort nicht wirklich gebraucht wird, aber trotzdem)? Niemand ist bereit, seine eigene Variante vorzuschlagen (man muss sich ja schließlich in Form halten)?

 
Vict:

Sie können es gerne verwenden.

Das obige Makro hat einen Nachteil - der Hilfstyp ist fest verdrahtet, man kann keine Funktion, die einen String zurückgibt, an Try

Warum nicht? Das +-Zeichen wurde noch nie gestrichen!

So habe ich Ihr Makro ausgekämmt und so werde ich es auch verwenden:

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

Der Makro-ParameterEXCEPT ist eine Ausnahme-Aktion, die als Rückgabe oder einfach als ; - funktioniert, wenn Sie sich entscheiden, die Ausgabe im Protokoll zu löschen, aber nicht den Körper OnTick() zu verlassen

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:

Nun, ich meine, es ist folgendermaßen:

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

Die Leute hier scheinen nicht zu spielen. Ach, kommen Sie.

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;                                         \
   }
Grund der Beschwerde: