Mql5 dilinin özellikleri, incelikleri ve çalışma yöntemleri - sayfa 31

 
Artyom Trishkin :

Gösterdiğim koda bile baktınız mı? Başlattın mı?

Gösterge arabelleğinin nasıl doldurulacağını değil, neden mevcut çubuktan değil AO'dan değerler alırsanız, boş değerler döndürüldüğünü sordum.
Bunu anladım - geçmiş yok - yükleniyor ve AO'yu yerel olmayan bir TF'den yüklerken "veri yok" hatası veriyor.

Şimdi soru şu: Gösterge döngüsüne girmemek için istenen TF'nin geçmişinin tam olarak yüklendiğini nasıl öğrenebilirim?

Başka bir göstergeden veri almak için bir göstergede CopyBuffer kullanırsanız , şunları yapmanız gerekir:

  1. Gösterge arabelleğinizi, grafikteki en sağdaki çubuk gösterge arabelleğindeki "0" dizinine karşılık gelecek şekilde çevirin.
  2. Böylece, "iMTF_AO.mq5" göstergesindeki "geçerli çubuk", grafikteki EN DOĞRU ÇUBUK olacak ve "Buffer[]" gösterge tamponundaki "0" indeksine karşılık gelecektir.
  3. Ve göstergeden (CopyBuffer(handle,0,shift,1,array)) "geçerli çubuğu" almak için "shift" parametresi "0"a eşit olmalıdır.

Gösterge arabelleğini çevirmek istemiyorsanız, şunu yapın (geçici olarak): AO(0) - bu, GÖSTERGEDEN BAŞKA BİR GÖSTERGE DEĞERLERİNİN nasıl alınacağını anlamak içindir. Belki bir veya iki kez bir hata ortaya çıkacaktır - ancak bu henüz bir zaman serisi oluşturulmamıştır ve daha sonra değerler istikrarlı bir şekilde döndürülecektir.

 
Artyom Trishkin :
cevabımı gördün mü Denedin mi?
 
Vladimir Karputov :

Başka bir göstergeden veri almak için bir göstergede CopyBuffer kullanırsanız , şunları yapmanız gerekir:

  1. Gösterge arabelleğinizi, grafikteki en sağdaki çubuk gösterge arabelleğindeki "0" dizinine karşılık gelecek şekilde çevirin.
  2. Böylece, "iMTF_AO.mq5" göstergesindeki "geçerli çubuk", grafikteki EN DOĞRU ÇUBUK olacak ve "Buffer[]" gösterge tamponundaki "0" indeksine karşılık gelecektir.
  3. Ve göstergeden (CopyBuffer(handle,0,shift,1,array)) "geçerli çubuğu" almak için "shift" parametresi "0"a eşit olmalıdır.

Gösterge arabelleğini çevirmek istemiyorsanız, şunu yapın (geçici olarak): AO(0) - bu, GÖSTERGEDEN BAŞKA BİR GÖSTERGE DEĞERLERİNİN nasıl alınacağını anlamak içindir. Belki bir veya iki kez bir hata ortaya çıkacaktır - ancak bu henüz bir zaman serisi oluşturulmamıştır ve daha sonra değerler istikrarlı bir şekilde döndürülecektir.

1. Kodumda , ve hemen oldu:

   ArraySetAsSeries (Buffer, true );
   int bars= Bars ( NULL ,PeriodForWork);
   datetime time_limit=GetTime( Symbol (),PeriodForWork,bars- 1 );
   int limit_p=GetBarShift( Symbol (), Period (),time_limit);
   if (rates_total< 1 ) return ( 0 );

2. Öyle.

3. shift, döngü indeksi i'ye eşittir. Ve döngü, tarihsel verilerin (rates_total-1) başlangıcından sonuna (mevcut verilere) kadar gider.

Diğer bir soru ise, eksik çubuklardan veri almamak için bu verileri yerel olmayan bir TF'ye göre hesaplamanız gerektiğidir. Ve döngüden önce, istenen TF'den gelen geçmişin tamamen senkronize olduğunu belirlemeniz gerekir.

 
Artyom Trishkin :

1. Kodumda , ve hemen oldu:

2. Öyle.

3. shift, döngü indeksi i'ye eşittir. Ve döngü, tarihsel verilerin (rates_total-1) başlangıcından sonuna (mevcut verilere) kadar gider.

Diğer bir soru ise, eksik çubuklardan veri almamak için bu verileri yerel olmayan bir TF'ye göre hesaplamanız gerektiğidir. Ve döngüden önce, istenen TF'den gelen geçmişin tamamen senkronize olduğunu belirlemeniz gerekir.


AO'ya erişim döngüsünü yeniden yapın: "0"dan bir değere ayarlayın (şimdi bir değerden sıfıra). Hatalar göründüğünde, hemen karşılaştırın: hesaplanan çubukların ("limit_p") sayısı ve mevcut göstergenin oranları_toplamını.


Eklendi: ve bu satırlar hesaplanan "limit"in tüm çabalarını siler (yerel olmayan bir zaman diliminden bahsediyorsak):

   if (limit> 1 ) 
     {
      limit=rates_total- 1 ;
     }

Kabaca söylemek gerekirse, ilk başta (yerel olmayan bir zaman diliminden bahsederken), "limit" 156'ya eşit ve BAM'ın altına düştü! ve "limit" zaten "154566666666" oldu



 
Alexey Kozitsyn :
Senkronizasyonu denediniz mi? Ayrıca geliştiriciler, gerekli TF/sembolün verilerini bir zamanlayıcı aracılığıyla güncel tutmayı tavsiye eder.

Hayır, henüz denemedim. Verilerin alaka düzeyini korumayı gördüm, hatırlıyorum, biliyorum.

Ancak başlangıçta, verilen TF ve mevcut olanın verileri henüz senkronize edilmemişse OnCalculate()'den çıkmanız gerekir.

Şu anki hakkında açık:

 if (rates_total< 1 ) return ( 0 );

Verilen hakkında - bunu kontrol etmeniz gerekiyor Barlar() - oranları_toplam yerine sayıları.

Ancak sınırı henüz çözemedim - şu anki TF'de şu şekilde kontrol edebilirsiniz (farklı bir göstergeden örnek olarak):

   int limit=rates_total-prev_calculated;
   if (limit> 1 ) {
      limit=rates_total- 4 ;
       ArrayInitialize (BufferAoDN, EMPTY_VALUE );
       ArrayInitialize (BufferAoUP, EMPTY_VALUE );
       ArrayInitialize (BufferMacdDN, EMPTY_VALUE );
       ArrayInitialize (BufferMacdUP, EMPTY_VALUE );
       ArrayInitialize (BufferRsiDN, EMPTY_VALUE );
       ArrayInitialize (BufferRsiUP, EMPTY_VALUE );
       ArrayInitialize (BufferStochDN, EMPTY_VALUE );
       ArrayInitialize (BufferStochUP, EMPTY_VALUE );
      }

Ancak bu test göstergesinde, hem mevcut TF'den (OnCalculate() içindeki hesaplamaları görüntüler) hem de belirtilenden - belirli bir TF'den AO verilerini elde etmek için veri alıyoruz.

Gerekli tüm verilerin çubuk sayısına göre nasıl güzel bir şekilde hesaplanacağı henüz aklıma gelmedi - sonuçta, mevcut TF'deki döngü, ilk mevcut verilerle geçmiş çubuğunun zamanına karşılık gelen çubuktan başlamalıdır. mevcut TF'den veya belirli bir tanesinden - daha azının olduğu yerde - o çubuktan ve döngüyü başlatın. Aynı zamanda, yeni bir çubuğun görünümünü yakalamak için, tam bir yeniden hesaplamaya veya yalnızca mevcut çubuğun yeniden hesaplanmasına (ne olduğuna bağlı olarak - yeni bir çubuk açmaya) yol açması gereken sınırın doğru bir şekilde hesaplanması gerekir. veya yükleme geçmişi).

Belki, her zamanki gibi, her şeyi aynı anda düşünmeye çalışıyorum ve çok fazla düşünüyorum...

 
Vladimir Karputov :


AO'ya erişim döngüsünü yeniden yapın: "0"dan bir değere ayarlayın (şimdi bir değerden sıfıra). Hatalar göründüğünde, hemen karşılaştırın: hesaplanan çubukların ("limit_p") sayısı ve mevcut göstergenin oranları_toplamını.


Eklendi: ve bu satırlar, hesaplanan "limit" in tüm çabalarını siler (yerel olmayan bir zaman dilimine atıfta bulunursak) :

Kabaca söylemek gerekirse, ilk başta (yerel olmayan bir zaman diliminden bahsederken), "limit" 156'ya eşit ve BAM'ın altına düştü! ve "limit" zaten "154566666666" oldu

Evet, hemen buraya aceleyle batırdığımı yazdım.

Ancak döngüyü kesinlikle yeniden yapmayacağım - her şeyin baştan sona geçmişin hesaplanması üzerine inşa edildiği oldukça karmaşık bir gösterge var - sınırları yeniden hesaplamak ve normal veri alımını elde etmek, tamamen yeniden yazmaktan daha kolaydır. tüm gösterge - tüm mantığı.

 
Artyom Trishkin :

Hayır, henüz denemedim. Verilerin alaka düzeyini korumayı gördüm, hatırlıyorum, biliyorum.

Ancak başlangıçta, verilen TF ve mevcut olanın verileri henüz senkronize edilmemişse OnCalculate()'den çıkmanız gerekir.

Şu anki hakkında açık:

Pek doğru değil. Göstergeli bir terminali yüklemeye başladığınızda beklediğinizi alamayabilirsiniz. Gün içerisinde ve bağlantının kesildiği zamanlarda da sıkışmalar olabilir.

OnCalculate()'den çıkmak hakkında: başlatma aşamasında Bars()'a ilk isteği yaparsınız, ardından OnCalculate()'de mevcut ve gerekli TF'lerin senkronizasyonunu kontrol edersiniz. Senkronizasyon yoksa - çıkın.

 
Artyom Trishkin :

Evet, hemen buraya aceleyle batırdığımı yazdım.

Ancak döngüyü kesinlikle yeniden yapmayacağım - her şeyin baştan sona geçmişin hesaplanması üzerine inşa edildiği oldukça karmaşık bir gösterge var - sınırları yeniden hesaplamak ve normal veri alımını elde etmek, tamamen yeniden yazmaktan daha kolaydır. tüm gösterge - tüm mantığı.

Artyom, "baştan sona" ne anlama geliyor?

Tüm dizileri çevirmenin en iyi yol olduğunu düşünüyor musunuz?

Ne için

 ArraySetAsSeries (Buffer, true );

sadece 1 değeri kopyalarsanız?

Geçerli olmayan bir TF kopyalarken, gerekli çubuğun zamanını CopyBuffer() işlevine geçirmek daha iyidir. Aksi takdirde, istediğiniz çubuk kopyalanmayacaktır.

 
Alexey Viktorov :

1. Artyom, "baştan sona" ne anlama geliyor?

2. Tüm dizileri ters çevirmenin en iyi çıkış yolu olduğunu düşünüyor musunuz?

3. Neden

4. Yalnızca 1 değeri kopyalarsanız?

Geçerli olmayan bir TF kopyalarken, gerekli çubuğun zamanını CopyBuffer() işlevine geçirmek daha iyidir. Aksi takdirde, istediğiniz çubuk kopyalanmayacaktır.

1. Geçmiş verilerin başlangıcı, en kısa açılış süresine sahip tarihteki ilk çubuktur, geçmiş verilerin sonu mevcut çubuktur.

2. Dörtten beşe yeniden yazarım.

3. Pekala, çünkü veriler, Rate_total-1'den 0'a kadar bir döngüde Buffer[]'a yazılır. Bunu bir zaman serisi olarak yapmazsanız, ekran grafikte arka arkaya olacaktır.

4. Verilen TF'nin i sütunundaki verilere karşılık gelen her seferinde bir değer kopyalarım.

not. Mevcut olmayan bir TF'den mql4'te veri almanın ne kadar kısa ve kolay olduğunu görün ve bunlar başarıyla elde edildi ve her şey istendiği gibi çalışıyor. Ve mql5'te gösterge verilerini almanın ne kadar garip ve hiçbir şekilde elde edilmiyorlar - göstergenin çalıştığı grafiğin zaman dilimine karşılık gelmeyen bir zaman dilimi AO veri toplama işlevine geçirilirse her zaman 4806 hatası .

 //+------------------------------------------------------------------+
double GetDataAO( string sy, int timeframe, int shift) {
   double array[ 1 ];
   ZeroMemory (array);
#ifdef __MQL4__
   array[ 0 ]= iAO (sy,timeframe,shift);
#else 
   ResetLastError ();
   if ( CopyBuffer (handle_ao, 0 ,shift, 1 ,array)== WRONG_VALUE ) {
       Print ( __FUNCTION__ , " > Error: " , GetLastError ());
       return ( 0 );
      }
#endif 
   return (array[ 0 ]);
}
//+------------------------------------------------------------------+

Aynı zamanda, OnInit() içinde, ayarlarda seçilen ilgili TF ile veri almanız gereken bir gösterge tutamacı oluşturulur:

handle_ao= iAO (symbol,periodForWork);

Yani, her zaman, herhangi bir zamanda, TF'yi nasıl değiştirirsek değiştirelim, tutamaç istenen (ayarlarda seçilen) TF ile oluşturulur. Ancak AO verileri, yalnızca ayarlarda seçilen TF, mevcut TF ile eşleşirse elde edilebilir. Eşleşmiyorlarsa, fonksiyondan her zaman sıfır döndürülür.

Soru: NEDEN?

 
Artyom Trishkin :

1. Tarihsel verilerin başlangıcı, en kısa açılış süresine sahip tarihteki ilk çubuktur, geçmiş verilerin sonu mevcut çubuktur.

2. Dörtten beşe yeniden yazarım.

3. Pekala, çünkü veriler, Rate_total-1'den 0'a kadar bir döngüde Buffer[]'a yazılır. Bunu bir zaman serisi olarak yapmazsanız, ekran grafikte arka arkaya olacaktır.

4. Verilen TF'nin i sütunundaki verilere karşılık gelen her seferinde bir değer kopyalarım.

not. Güncel olmayan bir TF'den mql4'te veri almanın ne kadar kısa ve kolay olduğunu görün ve bunların başarıyla elde edildiğini ve her şeyin amaçlandığı gibi çalıştığını görün. Ve gösterge verilerini mql5'te almanın ne kadar garip olduğu ve hiçbir şekilde elde edilmedikleri - göstergenin çalıştığı grafiğin zaman dilimine karşılık gelmeyen AO veri toplama işlevine bir zaman dilimi geçirilirse her zaman 4806 hatası .

Aynı zamanda, OnInit() içinde, ayarlarda seçilen ilgili TF ile veri almanız gereken bir gösterge tutamacı oluşturulur:

Yani, her zaman, herhangi bir zamanda, TF'yi nasıl değiştirirsek değiştirelim, tutamaç istenen (ayarlarda seçilen) TF ile oluşturulur. Ancak AO verileri, yalnızca ayarlarda seçilen TF, mevcut TF ile eşleşirse elde edilebilir. Eşleşmiyorlarsa, fonksiyondan her zaman sıfır döndürülür.

Soru: NEDEN?

1. Sadece bir açıklama. Şimdi aynı şeyden bahsettiğimiz açık.

2. Bunu anladım, ancak bunun için dizileri çevirmenin gerekli olduğuna katılmıyorum. İki terminal için bir göstergeye sahip olmak gerekli mi??? 2'si 1 arada tırpan ve balta yapmakla neredeyse aynı.

3. Buffer[] anladığım kadarıyla CopyBuffer() işlevinde alıcı tarafından sadece 1 gösterge değeri almak için kullanılıyor.

4. En önemli şeye dikkat etmediniz. Gösterge değerinin kopyalanmasının başlangıcı, çubuk indeksine göre değil, i-inci çubuğun zamanına göre belirlenmelidir.

 int    CopyBuffer ( 
   int        indicator_handle,     // handle индикатора 
   int        buffer_num,           // номер буфера индикатора 
   datetime   start_time,           // с какой даты 
   int        count,                 // сколько копируем 
   double     buffer[]               // массив, куда будут скопированы данные 
   );