Çoklu para birimi göstergesinin nasıl geliştirileceğini bilen var mı?

 
Çoklu para birimi göstergesinin nasıl geliştirileceğini bilen var mı?

1 ila 10 farklı para birimi ve her para birimi için 5 çubuk ARASINDA seçmek istiyorum.

Ama bunu nasıl yapacağımı bilmiyorum.

 

Standart bir göstergede, OnCalulate( ... ) olay işlevi aracılığıyla gönderilen parametrelerden gelen verilerle arabellek dizileri oluşturursunuz. Ancak, çoklu para birimi ve/veya çoklu zaman çerçevesi için iki çözümden birini kullanmanız gerekecektir:

  • iTime() , iVolume , iOpen , iClose vb. gibi "iFunction" varyasyonlarının eski yöntemini kullanarak ancak varsayılan _Symbol veya Symbol( yerine "EURUSD", "JPYUSD" vb. gibi farklı bir sembolle) ) .
  • ArrayCopyRates() işlevinin ilk değişkeninin daha yeni yöntemini MqlRates dizi işaretçileriyle birlikte kullanma. "Kopyalanmış" diziler aslında herhangi bir yer kaplamayacak ve sadece çeşitli sembollerin ve zaman çerçevelerinin mevcut verilerine işaretçiler olacaktır.

Bununla birlikte, bunun çalışması için, çoklu sembol ve/veya çoklu zaman çerçevesinin çalışması için iki koşuldan birinin mevcut olması gerekir:

  • Semboller ve zaman çerçeveleri için ilgili çizelgeler zaten açıktır, böylece hata oluşmaz,
  • veya verileri ilk talep ettiğinizde 4066 (ERR_HISTORY_WILL_UPDATED) hatası alırsınız ve verilerin indirilmesini beklemek ve ardından verileri tekrar istemek için bir uyku ve yeniden deneme döngüsü kodlamanız gerekir.

4066 hatasını işlemenin en verimli ve en kolay yolu olarak bulduğum kişisel önerilen çözümüm ArrayCopyRates() ve MqlRates yöntemidir.

Bununla ilgili daha fazla bilgi MQL4 belgeleri ve yardım dosyalarında bulunmaktadır.

not! Dikkat! Çeşitli semboller ve zaman çerçeveleri için iMA() , iATR() vb. gibi yerleşik gösterge işlevlerine erişirken, 4066 hatasını da almamak için uyku ve yeniden deneme döngülerini de uygulamayı unutmayın. İşte MQL4 dokümantasyonundan bir alıntı:

Any indicator can be calculated on the data of not only current chart, but also on the data of any available symbol/period. If data (symbol name and/or timeframe differ from the current ones) are requested from another chart, the situation is possible that the corresponding chart was not opened in the client terminal and the necessary data must be requested from the server. In this case, error ERR_HISTORY_WILL_UPDATED (4066 - the requested history data are under updating) will be placed in the last_error variable, and one will has to re-request (see example of ArrayCopySeries() )
 
OP'nin bir gösterge hakkında soru sorduğunu unutmayın. Sleep() göstergelerde yok sayılır
 
GumRai :
OP'nin bir gösterge hakkında soru sorduğunu unutmayın. Sleep() göstergelerde yok sayılır

Üzgünüm bunu bilmiyordum! Bu yöntemi EA'larda oldukça yaygın olarak kullanıyorum ancak Göstergelerde kullanmıyorum, bu yüzden uyku engelini bilmiyordum.

Bu durumda, OnCalculate() işlevine yapılan her tik çağrısında ( ArrayCopyRates() kullanımının daha iyi bir çözüm olduğu yerde) ardışık çağrılar etrafında bir yeniden deneme döngüsü oluşturması gerekecektir.

Alternatif olarak, OnInit() işlevinde çalışıyorsa, bu durumda çok uzun bir yeniden deneme sayısıyla (uyku olmadan) gösterge için verileri hazırlamak için tercih edilen yöntem olabilir.

 
FMIC :

...

  • veya verileri ilk talep ettiğinizde 4066 (ERR_HISTORY_WILL_UPDATED) hatası alırsınız ve verilerin indirilmesini beklemek ve ardından verileri tekrar istemek için bir uyku ve yeniden deneme döngüsü kodlamanız gerekir.

not! Dikkat! Çeşitli semboller ve zaman çerçeveleri için iMA() , iATR() vb. gibi yerleşik gösterge işlevlerine erişirken, 4066 hatasını da almamak için uyku ve yeniden deneme döngülerini de uygulamayı unutmayın. İşte MQL4 dokümantasyonundan bir alıntı:


Yakın zamanda bir şeyi değiştirmedikleri sürece, koşullardan veya geçmiş güncellemesinin ilerlemesinden bağımsız olarak, ilk işlev çağrısından (ve yalnızca bu ilk çağrıdan) itibaren her seferinde 4066 hatasını alırsınız. Pratik bir kullanımı yoktur.
 
Ovo :
Yakın zamanda bir şeyi değiştirmedikleri sürece, koşullardan veya geçmiş güncellemesinin ilerlemesinden bağımsız olarak, ilk işlev çağrısından (ve yalnızca bu ilk çağrıdan) itibaren her seferinde 4066 hatasını alırsınız. Pratik bir kullanımı yoktur.
Bu bende böyle olmadı. Veriler zaten tamamen mevcut olduğunda, 4066 hatasını almıyorum. Ancak, doğrudan mevcut değilse, o zaman evet, o belirli sembol ve zaman çerçevesi için herhangi bir işlevin yalnızca ilk çağrısında hatayı alıyorum. Bundan sonra, bu verileri isteyen diğer işlevler artık hata vermez.
 

FMIC :

Bu durumda, OnCalculate() işlevine yapılan her tik çağrısında ( ArrayCopyRates() kullanımının daha iyi bir çözüm olduğu yerde) ardışık çağrılar etrafında bir yeniden deneme döngüsü oluşturması gerekecektir.

Alternatif olarak, OnInit() işlevinde çalışıyorsa, bu durumda çok uzun bir yeniden deneme sayısıyla (uyku olmadan) gösterge için verileri hazırlamak için tercih edilen yöntem olabilir.

  1. Göstergedeki bir döngü (uzun veya başka türlü) çalışmayacaktır . Gösterge çalışırken terminalde başka hiçbir şey olamaz. Bu yüzden Uyku indikatörlerde çalışamaz. Ve neden ArrayCopyRates eşzamansız (göstergeler için).
  2. init'te oranlar dizisini etkinleştirin. OnTick'te test edin ve yeniden denemeleri orada yapın. Ayrıca farklı çizelgelerin farklı zamanlarda yeni çubuklar oluşturduğunu unutmayın.
     string pairs[] = { "EURUSD" , "GBPUSD" ...}
    MqlRates pair0[], pair1[], ...
    bool initial;
    OnInit (){ initial= true ;
       ArrayCopyRates(pair0, pairs[ 0 ], _Period );   
       ArrayCopyRates(pair1, pairs[ 1 ], _Period );
       :
    }
    OnCalculate ( ... ){
       int count = IndicatorCounted();
       if (initial){
           if (pair 1 [ 0] .time == 0 ) return ;
           if (pair 2 [ 0 ].time == 0 ) return ;
          :
          initial= false ; count = 0 ; // process all bars
       }
       for ( int i = Bars - 1 - MathMax (lookback, count); i >= 0 ; --i){
           int shift0 = iBarsShift(pairs[ 0 ], _Period , Time[i]);
           int shift1 = iBarsShift(pairs[ 1 ], _Period , Time[i]);
          buffer[i] = pair 0[ shift0 ].close - pair 1[ shift1 ].close;

  3. ArrayCopyRates kullanmak istemiyorsanız, buna gerek yoktur, ancak yine de [in the if(initial) ] öğesini pairN[0].time ile iTime() değiştirerek diğer çiftleri yüklemelisiniz.
 
   if (pair1[ 0 ].time == 0 ) return ;

Bu asla doğru olmayacak.

Sembol ve zaman çerçevesi için yüklenmiş herhangi bir geçmiş varsa, fonksiyon en son değeri alacaktır.

Yüklenmiş bir geçmiş yoksa, bir Dizi aralık dışı hatası alırsınız.

iTime vb. ile aynı

 
GumRai :

Bu asla doğru olmayacak.

Sembol ve zaman çerçevesi için yüklenmiş herhangi bir geçmiş varsa, fonksiyon en son değeri alacaktır.

Yüklenen bir geçmiş yoksa, bir Dizi aralık dışı hatası alırsınız.

iTime vb. ile aynı

Kabul etmeye meyilliyim!

Şahsen, "ArrayCopyRates()" in dönüş değerini kontrol ediyorum ve bundan sonra dizi verilerine erişmeden önce dizi boyutunu takip ediyorum.

"iTime()" ve benzeri diğer işlevlerle ilgili olarak, her zaman önce "iBars()" öğesini kontrol ederim.

 
GumRai :

Bu asla doğru olmayacak.

  if (pair1[ 0 ].time == 0 ) return ;

Sembol ve zaman çerçevesi için yüklenmiş herhangi bir geçmiş varsa, fonksiyon en son değeri alacaktır.

Yüklenmiş bir geçmiş yoksa, bir Dizi aralık dışı hatası alırsınız.

iTime vb. ile aynı

Bir ACR'ye bakmanın birçok tarihi (yapım öncesi 600) örneği vardır. Bunu yapmanın başka bir yolu yok. ACR veya iTime'a yapılan sonraki aramalar 4066'yı ÇIKARMAYACAKTIR, bu nedenle verilerin indirilip indirilmediğini nasıl bilebilirsiniz.

iTime bir hatada her zaman sıfır döndürdü.

 
WHRoeder :

Bir ACR'ye bakmanın birçok tarihi (yapım öncesi 600) örneği vardır. Bunu yapmanın başka bir yolu yok. ACR veya iTime'a yapılan sonraki aramalar 4066'yı ÇIKARMAYACAKTIR, bu nedenle verilerin indirilip indirilmediğini nasıl bilebilirsiniz.

iTime bir hatada her zaman sıfır döndürdü.

"Başka yolu yok" derken ne demek istiyorsun?

"ArrayCopyRates" öğesinden dönüş sayısını kontrol etmek ve dizi boyutunu kontrol etmek, kolayca " Dizi indeksi aralık dışı " döndürebilen "pair1[0].time == 0" yapmaktan daha sağlam bir kontrol yöntemi gibi görünüyor. " hata.

EDIT: Gönderinizi daha yakından okuduktan sonra bazı ifadelerimi kaldırdım.