[SERVICE DESK] Zamanlayıcıda kıdemli TF'nin zamanı alınırken hata oluştu! - sayfa 6

 
Geliştiricilerin bu konuda ne düşündüğünü duymak isterim.
 
 ResetLastError();
      if(iBarShift(Symbol(),PERIOD_M15,TimeCurrent(),true)==-1)
        {
         Print(__FILE__+": Данные истории по последнему часу отсутствуют! Ошибка #",GetLastError());
         return( false );
        }
      //---
      if(GetLastError()==ERR_NO_ERROR)
        {
         ResetLastError();
         //--- Запоминаем время открытия бара
         _m15OpenTime=iTime(NULL,PERIOD_M15,0);
         //---
         Print(__FILE__,": Актуальное время открытия бара М15 = "+TimeToString(_m15OpenTime)+". Ошибка #",GetLastError());
         //--- Возвращаем истину
         return( true );
        }
 
Alexey Kozitsyn :

Görünüşe göre en güvenilir çözüm, OnCalculate() çağrısını gerçekten beklemek ve ticaret sunucusuyla bağlantı kurmanın zorunlu kontrolünü yapmak. Bağlantıyı kontrol etmezsek (IsConnected()), o zaman OnCalculate() içinde bile terminali yüklerken şunu elde ederiz:

Ancak, bu tüm soruları çözmez:

1. OnCalculate() içindeki kıdemli TF'nin verilerini (en azından) almadan önce çağrılması gerektiği IsConnected() belgelerinde neden yazılmıyor?

2. OnTimer() içindeki IsConnected() neden gerçekten çalışmıyor? Sonuçta bir ticaret sunucusuyla bağlantı kurmanın bize veri almanın mümkün olduğunu söylemesi gerekmez mi?

3. Ticaret sunucusuyla bir bağlantı kurduğumuz ve OnTimer()'da veri almaya çalıştığımız için, iTime(), iBarShift(), SeriesInfoInteger() ve benzer işlevler, veriler aynı kaynaktan geliyorsa hata döndürmemelidir. bilgileri aldıkları ticaret sunucusu henüz senkronize değil mi? Aksi takdirde, bir zamanlar size 4066 hatasını döndüreceğimiz ve daha sonra sahip olduğunuz verilerle istediğiniz gibi yaşayacağımız gibi bir tür saçmalık ortaya çıkıyor.

Geliştiricilerle konuştum, orada bir arkadaşım var, onlara nokta nokta anlatıyorum.

1 Saçmalık, istediğiniz zaman ve istediğiniz yerden arayabilirsiniz.

2 IsConnected, kodun herhangi bir yerinden çağrılabilir ve çalışır, ancak hata yığınına hiçbir şey yazmayan bir işlevdir, doğru/yanlış döndürür ve bu kadar. Bağlantı prosedürünün oldukça uzun (en az 1 sn) olduğu ve IsConnected'in oturum açma başlangıcında zaten tetiklendiği göz önüne alındığında, bağlantı durumunu kontrol etmek ve terminal koşullarında teklif akışının başlamasını beklemek gerekir. Başlat.

3 Bu işlevler ayrıca hata yığınına hiçbir şey yazmaz, çalışmanın sonucunu kendileri döndürür.

Neden 4066 alıyoruz, TimeCurrent işlevinden bir hataydı. Bir oturum açıldı, terminalin sunucudan istediği süre, bağlantının kalitesine bağlı olarak bu da biraz zaman alıyor, hızlı bir zamanlayıcımız olduğunu unutmayın. Sonra TimeCurrent'tan isteğimiz üzerine 4066 aldık. Ve sonra zamanımız oldu ve fonksiyonlarımız normal şekilde çalışmaya başladı; çalışmalarının sonucunda kendileri hata yığınını atlayarak bir hata veriyorlar.

Böyle bir durumda bir öneri olarak, hızlı bir zamanlayıcı ve terminalin başlatılması, sunucudan veri almaya başladığımızdan emin olun. Versiyonum biraz zor, OnCalculate'den veri alımının başlangıcı hakkında bir sinyal almak doğru olur.

 
Her şey daha kolay.
 
Alexey Kozitsyn :

Sorunu çözmek için ne öneriyorsunuz (sence var mı)? OnCalculate() 1-2 kez çağrılana kadar bekleyin?

Evet öyle. OnInit()'te, sonucu kontrol etmeden gerekli TF'lere bir çağrı yaparsınız (orada buna güvenemezsiniz) ve zaten OnCalculate'de IsTFDataReady() işlevini çağırırsınız. İstenen tüm TF'ler için true değeri döndürülür döndürülmez, gösterge algoritmasını yürütmeye başlayabilirsiniz.

 
Alexey Kozitsyn :

1. OnCalculate() içindeki kıdemli TF'nin verilerini (en azından) almadan önce çağrılması gerektiği IsConnected() belgelerinde neden yazılmıyor?

IsConnected() oldukça zor bir fonksiyondur. Sunucuya yapılan bağlantılardan yalnızca birinin durumunu döndürür. Ancak terminal birden fazla bağlantı kullanır. Tek başına 8 ticaret akışı vardır, bu nedenle IsConnected() true dönse bile bunun ne anlama geldiği tam olarak açık değildir. En azından, zaman serilerinin talep edilmesini ve oluşturulmasını bekleyemezsiniz. IsConnected() false döndürürse, terminalin hala çevrimdışı olduğundan emin olabilirsiniz.

Genel olarak, bir terminal bağlantısının varlığının çok önemli olduğu ne tür bir görev çözülüyor? Anladığım kadarıyla, bir gösterge bir veri görselleştirme aracıdır. Mevcut olan veriler. Yeni veriler geldiğinde, görselleştirmeyi güncelleyecektir. Ondan, verilerin alaka düzeyinin kontrolü gerekli olmamalıdır. Bu terminalin görevidir.

 
Igor Makanu :

muhtemelen hala OHLC'nin hazırlanmasının MT4'teki ile aynı olmadığı MQL5'ten bahsediyoruz

MT4'ten bahsediyorum. 2-3 yıl önce Time[0] ile ilgili bir hata yakaladım. Geliştiriciler düzeltmiş gibi görünüyor, ancak zamanla tekrar ortaya çıktı. Sorun, bu hatayı açık bir şekilde yeniden oluşturmanın imkansız olmasıdır.

 
Ihor Herasko :

IsConnected() oldukça zor bir fonksiyondur. Sunucuya yapılan bağlantılardan yalnızca birinin durumunu döndürür. Ancak terminal birden fazla bağlantı kullanır. Tek başına 8 ticaret akışı vardır, bu nedenle IsConnected() true dönse bile bunun ne anlama geldiği tam olarak açık değildir. En azından, zaman serilerinin talep edileceğine ve oluşturulacağına güvenemezsiniz. IsConnected() false döndürürse, terminalin hala çevrimdışı olduğundan emin olabilirsiniz.

Genel olarak, bir terminal bağlantısının varlığının çok önemli olduğu ne tür bir görev çözülüyor? Anladığım kadarıyla, bir gösterge bir veri görselleştirme aracıdır. Mevcut olan veriler. Yeni veriler geldiğinde, görselleştirmeyi güncelleyecektir. Ondan, verilerin alaka düzeyinin kontrolü gerekli olmamalıdır. Bu terminalin görevidir.

göstergelerde, sunucuyla bağlantıyı, geçmişte ne olduğunu kontrol etme ihtiyacını gerçekten hatırlamıyorum, sonra çiziyoruz, geçmiş yüklendi, bu yüzden tüm gösterge arabelleklerini yeniden hesaplayacağız

Danışmanda aşağıdaki işlevi yaptım ve kullanıyorum, prensipte uygun ve sunucu ile bağlantıyı doğru şekilde kontrol ediyor:

 bool ServerDisable( int count= 10 ){
   if ( IsTesting ()|| IsOptimization ()) return ( false );
   for ( int i= 0 ;i<count;i++){
       if ( IsConnected ())
         if ( IsTradeAllowed ())
             if (! IsTradeContextBusy ()){ RefreshRates (); return ( false );}
       Sleep ( 157 );
   }
   Print ( __FUNCTION__ , " Торговый сервер не отвечает" );
return ( true );}

Kontrolü terminale aktarmak için özellikle Sleep() kullanıyorum ve sonra tekrar sunucu bağlantısını ve ticaret olasılığını kontrol ediyorum.

 
Ihor Herasko :

MT4'ten bahsediyorum. 2-3 yıl önce Time[0] ile ilgili bir hata yakaladım. Geliştiriciler düzeltmiş gibi görünüyor, ancak zamanla tekrar ortaya çıktı. Sorun, bu hatayı açık bir şekilde yeniden oluşturmanın imkansız olmasıdır.

zorlaştırmıyorsa, işte konunun konusu - eski TF'den tarihin doğru yüklenmesi, işte gösterge: genç TF'nin çubuklarında eski TF'den "Masha çizmeniz gerekiyor", yaptı 5 dakika içinde, %98 tam olarak doğru çalışacak, bu kodda %2 "tuzaklar" hangi hatalara neden olacak?

MT4 için doğru kodla ilgileniyor

 #property copyright "IgorM"
#property link        "https://www.mql5.com/ru/users/igorm"
#property version    "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 1
#property indicator_plots    1
//--- plot line1
#property indicator_label1    "line1"
#property indicator_type1    DRAW_LINE
#property indicator_color1    clrRed
#property indicator_style1    STYLE_SOLID
#property indicator_width1    1
//--- input parameters
input ENUM_TIMEFRAMES    TimeFrame   =   PERIOD_H4 ;
input int                MAPeriod    =   25 ;
//--- indicator buffers
double          BufMA[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit ()
  {
   double cl[];
//--- indicator buffers mapping
   SetIndexBuffer ( 0 ,BufMA);
   IndicatorDigits ( Digits );
// запускаем подгрузку истории и выходим, даже не проверяя подгружена она или нет, история тут еще не нужна
   CopyClose ( _Symbol ,TimeFrame, 0 , iBars ( _Symbol ,TimeFrame),cl);
//---
   return ( INIT_SUCCEEDED );
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate ( const int rates_total,
                 const int prev_calculated,
                 const datetime &time[],
                 const double &open[],
                 const double &high[],
                 const double &low[],
                 const double &close[],
                 const long &tick_volume[],
                 const long &volume[],
                 const int &spread[])
  {
//---
   int i,limit,resultcopy;
   double closetf[];
   if (prev_calculated== 0 )
     {
      resultcopy= CopyClose ( _Symbol ,TimeFrame, 0 , iBars ( _Symbol ,TimeFrame),closetf);
       if (resultcopy< 0 )
        {
         Print ( "Подгрузка истории...." );
         return ( 0 );
        }
       if (resultcopy<MAPeriod)
        {
         Comment ( "Большой период МА!!!, в истории доступно " , resultcopy, " баров" );
         return (resultcopy);
        }
      limit=resultcopy- 1 ;
        } else {
      resultcopy= CopyClose ( _Symbol ,TimeFrame, 0 , iBars ( _Symbol ,TimeFrame),closetf);
       if (resultcopy< 0 )
        {
         Print ( "Подгрузка истории...." );
         return ( 0 );
        }
       if (resultcopy<MAPeriod)
        {
         Comment ( "Большой период МА!!!, в истории доступно " , resultcopy, " баров" );
         return (resultcopy);
        }
      limit=resultcopy-prev_calculated+ 1 ;
     }
   limit = fmin (rates_total- 1 ,limit);
// основной цикл расчета индикатора
   for (i=limit; i>= 0 && ! IsStopped (); i--)
     {
      BufMA[i]= iMA ( _Symbol ,TimeFrame,MAPeriod, 0 , MODE_SMA , PRICE_CLOSE ,i);
     }
//---
   return (resultcopy);

  }
 
Vitaly Gorbunov :

Geliştiricilerle konuştum, orada bir arkadaşım var, onlara nokta nokta anlatıyorum.

1 Saçmalık, istediğiniz zaman ve istediğiniz yerden arayabilirsiniz.

2 IsConnected, kodun herhangi bir yerinden çağrılabilir ve çalışır, ancak hata yığınına hiçbir şey yazmayan bir işlevdir, doğru/yanlış döndürür ve bu kadar. Bağlantı prosedürünün oldukça uzun (en az 1 sn) olduğu ve IsConnected'in oturum açma başlangıcında zaten tetiklendiği göz önüne alındığında, bağlantı durumunu kontrol etmek ve terminal koşullarında teklif akışının başlamasını beklemek gerekir. Başlat.

3 Bu işlevler ayrıca hata yığınına hiçbir şey yazmaz, çalışmanın sonucunu kendileri döndürür.

Neden 4066 alıyoruz, TimeCurrent işlevinden bir hataydı. Bir oturum açıldı, terminalin sunucudan istediği süre, bağlantının kalitesine bağlı olarak bu da biraz zaman alıyor, hızlı bir zamanlayıcımız olduğunu unutmayın. Sonra TimeCurrent'tan isteğimiz üzerine 4066 aldık. Ve sonra zamanımız oldu ve fonksiyonlarımız normal şekilde çalışmaya başladı; çalışmalarının sonucunda kendileri hata yığınını atlayarak bir hata veriyorlar.

Böyle bir durumda bir öneri olarak, hızlı bir zamanlayıcı ve terminalin başlatılması, sunucudan veri almaya başladığımızdan emin olun. Versiyonum biraz zor, OnCalculate'den veri alımının başlangıcı hakkında bir sinyal almak doğru olur.

1. Yazdıklarımı dikkatlice okuyun. İlk kez konuşmuyorum! Bir yerde arama engellemeden bahsetmedim!

Tüm iBarShift() , iTime() , SeriesInfo...() işlevlerinin TimeCurrent() zaman sorduğunu mu söylüyorsunuz?