MT4'ten MT5'e aktarma sorunu. Veya daha doğrusu, MT5'te bazı algoritmaların hatasız yürütülmesinin imkansızlığı. - sayfa 10

 
Vict :

Garip, ama daha önce yapmayı düşünmedim:

Bellek ayırma gibi birçok hata kontrolünden kurtulur.

bir seçenek değil, danışman çizelgeden kaldırılacaktır, ancak programın herhangi bir yerinden bir sonraki onay işaretinden önce "işletim sistemine çıkmanız" yeterlidir.


büyük olasılıkla, her şeyi bir makroya zarif bir şekilde sarabilirsiniz, böylece mevcut kene üzerindeki verilere erişilemezlikle ilgili işlevleri güvenli bir şekilde çağırmanız gerektiğinde, işte "boş"

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

Kodun okunabilirliği için şöyle yazmak istiyorum:

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


Bu Deneme, başarısızlık durumunda sarmak ve "işletim sisteminden çıkmak" için gerçekten bir makroda mı?

 
Igor Makanu :

Bu Deneme, başarısızlık durumunda sarmak ve "işletim sisteminden çıkmak" için gerçekten bir makroda mı?

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

Değil?

Genellikle her türlü mini makroyu fonksiyonun hemen başında yazarım ve sonunda tanımsız hale getiririm. Doğal olarak, eylem sık sık tekrarlanırsa, aksi takdirde anlamsızdır.

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

Ve kürtaj hakkında, boşuna yani, bazı hatalarla, mükemmel.

 
Vict :

Değil?

Evet!

ama ideal olarak bunun yerine şunu isterim:

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

Böyle:

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

Open() işlevinin imzasını değiştirmeniz gerekiyorsa bu bir soru değil... ama bu formda, gerçekten istediğim şeyi elde edeceğim! ;)

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

Not: bir seçenek olarak, global olarak bildirilen değişkenler Tryerror veya bool Tryresult bile uygundur - bu çağrı OnTick() gövdesinden çıkamazsa amaç tek satırlık "güvenli çağrı"dır

 
Igor Makanu :

Böyle:

Profesyonellerde bile bunun mümkün olduğundan şüpheliyim (bir istisna atabilirsiniz, ancak geri dönüş olası değildir). Ama her şey olabilir, belki birileri şaşırtacak ...

 

Pekala, hazırlıksız:

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

Belki de bu durumda maksimum budur.

 

aptalım, belki

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

Derlemedi ama çalışması gerekir.

 
Vict :

Ben tamamen aptalım, belki

Derlemedi ama çalışması gerekir.

Şeytan bir makinedir!!! kazanıldı!!!

test edilmiş ve simüle edilmiş hata ( 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) Hata: bir şeyler ters gidiyor


Güzel! ve makro kodunun gerçekten basit olduğu ortaya çıktı


TEŞEKKÜR ETMEK! Sen kesinlikle bir sihirbazsın! ;)

 

Lütfen sağlıklı kullanın.

Yukarıdaki makronun bir dezavantajı vardır - yardımcının türü sabit kodlanmıştır, dize döndüren bir işlev iletemezsiniz ve ardından iki makro oluşturmadan Try'e iki katına çıkarabilirsiniz. Sportif bir ilgim vardı - bunun üstesinden nasıl gelebilirim (her tür için bir makro yazın. Seçenekler olmadan µl'de, c ++'da, orada gerçekten gerekli olmasa da, yine de)? Hiç kimse kendi versiyonunu sunmak istemiyor (peki, kendinizi formda tutmanız gerekiyor)?

 
Vict :

Lütfen sağlıklı kullanın.

Yukarıdaki makronun bir dezavantajı vardır - yardımcının türü kabloludur, dize döndüren bir işlevi Try'e iletemezsiniz

neden? + işaretini kimse iptal etmedi!

Şimdi, kullanmayı planladığım gibi makronuz şu şekilde tarandı:

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

şimdi HARİÇ makro parametresi bir istisna eylemidir, sadece dönüş kadar iyi çalışır; - günlüğe yazdırmaya karar verirseniz, ancak OnTick() gövdesinden ayrılmayın

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) : hata No. 999 bir şeyler ters gidiyor Txt

 
Igor Makanu :

Pekala, bunu şu şekilde kullanmak üzereyim:

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

Buradaki insanların kumar oynamadığı bir şey. her neyse

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