MT4 iMAOnArray ve iBandsOnArray eleman sayısının hesaplamalar üzerindeki etkisi - sayfa 2

 
Sergey Efimenko :
Ne bekliyorum? Yukarıda, diziye 299-0 uzaklığında erişmeme rağmen, ilk 300'e (başlangıç) değil, son 300 (geçerli) gerçek değere ihtiyacım olduğunu yazdım, ancak "sonundan ofsette veri alıyorum. dizi" - " dizinin sonu - 300 "değerleri (benim durumumda 4999'dan 4700'e kadar), yani 299'da ofset 4999'da olması gereken bir değer var ve benzer şekilde ofset 0'da bir değer var ofset 4700'de olması gereken değer. İlk tarihsel verileri değil, mevcut olanları almak için dizi hesaplamalarının sayısını azaltırken, asıl soru, hesaplamanın hesaplanması gerçeğine rağmen, en eski değerleri hesaplamanın amacı nedir? şimdikiler yapılmadı mı?

Yazdıklarınız anlaşılır olsaydı, o zaman soru olmazdı.

 double    iMAOnArray (
   double        array[],           // массив               // С этим понятно...
   int           total,             // количество элементов // Это у тебя 300
   int           ma_period,         // период               // Это ???
   int           ma_shift,         // сдвиг средней        // понятно
   int           ma_method,         // метод усреднения     // понятно
   int           shift             // сдвиг                // А здесь чему равна i???
   );

Sizden bir kod örneği göstermeniz istendi ve siz örneğin sadece bir parçasını gösterdiniz. Gerisi sadece her şeyin döngüde olduğunu tahmin edebilirsiniz. i'nin hangi değerinde son, mevcut değerleri almak istiyorsunuz ??? i = 4700 veya nerede?

 
Alexey Viktorov :

Yazdıklarınız anlaşılır olsaydı, o zaman soru olmazdı.

Sizden bir kod örneği göstermeniz istendi ve siz örneğin sadece bir parçasını gösterdiniz. Gerisi sadece her şeyin döngüde olduğunu tahmin edebilirsiniz. i'nin hangi değerinde son, mevcut değerleri almak istiyorsunuz ??? i = 4700 veya nerede?

Belirtilen işlevleri pratikte hesaplanan dizinin uzunluğu üzerinde bir sınırlama ile kullandıysanız, bunun ne hakkında olduğunu anlayacaksınız, aksi takdirde teorik akıl yürütmenin amacı nedir?.. Ve benim kodumda anlaşılmaz olan nedir? İlk durumda diziyi hesaplamak için uzunluk sınırını kullanmadığım tek farkla kesinlikle aynı bölümleri verdim. Bu durumda, hangi hesaplama periyodu, ortalama kayma veya ortalama alma yönteminin hiçbir önemi yoktur, çünkü her iki durumda da aynılar mı? Üstte yazdığım gibi shift değeri de aynı şekilde kullanılıyor. Belirtilen satırları normal olarak yapılan ve yalnızca yeni çubukları sayan herhangi bir göstergeye sürün, "i"yi döngüdeki ofset değişkeninizle değiştirin, GetValue(i) işlevini en az Open[i] ile değiştirin, belirtilen üç diziyi yapın 3 göstergenin arabelleklerini görüntüleyin ve ilk seçeneğin ve ikincisinin nasıl çalıştığını görün. Bununla birlikte, sorunun özünü anlamayı basitleştirmek için göstergenin en basit sürümünün tam kodunun iki versiyonuna bir örnek:

// bu iyi çalışıyor:
 #property strict
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 clrYellow
#property indicator_color2 clrGreen
#property indicator_color3 clrRed
double Buffer[],BufferMA[],BufferBMA[]; bool firstrun= true ;
int init() { firstrun= true ; SetIndexBuffer ( 0 ,Buffer); SetIndexBuffer ( 1 ,BufferMA); SetIndexBuffer ( 2 ,BufferBMA); return ( 0 ); }
int start() { int i,limit; int counted_bars= IndicatorCounted (); if (counted_bars< 0 ) return (- 1 ); if (counted_bars> 0 ) counted_bars--; limit= Bars -counted_bars- 1 ;
   if (firstrun) { ArrayInitialize (Buffer, Open [ Bars - 1 ]); ArrayInitialize (BufferMA, Open [ Bars - 1 ]); ArrayInitialize (BufferBMA, Open [ Bars - 1 ]); firstrun= false ; }
   for (i=limit; i>= 0 ; i--) { Buffer[i]= Open [i]; BufferMA[i]= iMAOnArray (Buffer, 0 , 12 , 0 , 0 ,i); BufferBMA[i]= iBandsOnArray (Buffer, 0 , 12 , 2 , 0 , MODE_MAIN ,i); }
return ( 0 ); }

// şu şekilde çalışmıyor:

 #property strict
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 clrYellow
#property indicator_color2 clrGreen
#property indicator_color3 clrRed
double Buffer[],BufferMA[],BufferBMA[]; bool firstrun= true ;
int init() { firstrun= true ; SetIndexBuffer ( 0 ,Buffer); SetIndexBuffer ( 1 ,BufferMA); SetIndexBuffer ( 2 ,BufferBMA); return ( 0 ); }
int start() { int i,limit; int counted_bars= IndicatorCounted (); if (counted_bars< 0 ) return (- 1 ); if (counted_bars> 0 ) counted_bars--; limit= Bars -counted_bars- 1 ;
   if (firstrun) { ArrayInitialize (Buffer, Open [ Bars - 1 ]); ArrayInitialize (BufferMA, Open [ Bars - 1 ]); ArrayInitialize (BufferBMA, Open [ Bars - 1 ]); firstrun= false ; }
   for (i=limit; i>= 0 ; i--) { Buffer[i]= Open [i]; BufferMA[i]= iMAOnArray (Buffer, 300 , 12 , 0 , 0 ,i); BufferBMA[i]= iBandsOnArray (Buffer, 300 , 12 , 2 , 0 , MODE_MAIN ,i);  }
return ( 0 ); }

Göstergeleri grafiğe yerleştirdikten sonra , grafiğin başına (solda) gidin ve 12. çubuktan 1 numaralı göstergeye bakın ve bundan sonra 2. ve 3. dizilerin "boş olmayan" doldurulması başlar. , kabaca 0'dan farklı olan ilk birkaç değeri hatırlayın, ardından grafiği mevcut alıntılara taşıyın ve 300 bar'dan başlayan değerlere bakın, böylece 2 (alt) göstergenin değerleri eşit olacaktır. 1. gösterge için grafiğin başında gördükleriniz, ancak teorik olarak değerler mevcut değerlerle eşleşmelidir. Umarım net bir şekilde anlatmışımdır. Ek olarak, çizelgeleri çevrimiçi bir çizelgeye koyarsanız, ilki iyi çalışır ve ikincisi "kendi başına asılır".

 
Sergey Efimenko :


Kod yalnızca stilsiz olmakla kalmaz, aynı zamanda kodu düz metin biçiminde de eklersiniz. Lütfen kodu doğru yapıştırın.
 

Kodunuzu daha okunabilir bir biçimde ve yeni bir gösterimde sunayım (gerçekten, bu anakronizmi int start()??? indikatörlerinde ne kadar süre kullanabilirsiniz):

Gösterge 1:

 //+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property version    "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 clrYellow
#property indicator_color2 clrGreen
#property indicator_color3 clrRed
double Buffer[];
double BufferMA[];
double BufferBMA[];
bool firstrun= true ;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit ()
  {
//--- indicator buffers mapping
   firstrun= true ;
   SetIndexBuffer ( 0 ,Buffer, INDICATOR_DATA );
   SetIndexBuffer ( 1 ,BufferMA, INDICATOR_DATA );
   SetIndexBuffer ( 2 ,BufferBMA, INDICATOR_DATA );
//---
   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;
   limit=rates_total-prev_calculated- 1 ;
   if (prev_calculated== 0 )
     {
       ArrayInitialize (Buffer,open[rates_total- 1 ]);
       ArrayInitialize (BufferMA,open[rates_total- 1 ]);
       ArrayInitialize (BufferBMA,open[rates_total- 1 ]);
     }
   for (i=limit; i>= 0 ; i--)
     {
      Buffer[i]=open[i];
      BufferMA[i]= iMAOnArray (Buffer, 0 , 12 , 0 , MODE_SMA ,i);
      BufferBMA[i]= iBandsOnArray (Buffer, 0 , 12 , 2 , 0 , MODE_MAIN ,i);
     }
   return (rates_total);
  }
//+------------------------------------------------------------------+

Gösterge 2:

 //+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property version    "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 clrYellow
#property indicator_color2 clrGreen
#property indicator_color3 clrRed
double Buffer[];
double BufferMA[];
double BufferBMA[];
bool firstrun= true ;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit ()
  {
//--- indicator buffers mapping
   firstrun= true ;
   SetIndexBuffer ( 0 ,Buffer, INDICATOR_DATA );
   SetIndexBuffer ( 1 ,BufferMA, INDICATOR_DATA );
   SetIndexBuffer ( 2 ,BufferBMA, INDICATOR_DATA );
//---
   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;
   limit=rates_total-prev_calculated- 1 ;
   if (prev_calculated== 0 )
     {
       ArrayInitialize (Buffer,open[rates_total- 1 ]);
       ArrayInitialize (BufferMA,open[rates_total- 1 ]);
       ArrayInitialize (BufferBMA,open[rates_total- 1 ]);
     }
   for (i=limit; i>= 0 ; i--)
     {
      Buffer[i]=open[i];
      BufferMA[i]= iMAOnArray (Buffer, 300 , 12 , 0 , MODE_SMA ,i);
      BufferBMA[i]= iBandsOnArray (Buffer, 300 , 12 , 2 , 0 , MODE_MAIN ,i);
     }
   return (rates_total);
  }
//+------------------------------------------------------------------+

Ve yürütme sonucu:

Sonuç

hakkında

Dosyalar:
Test.mq4  3 kb
Test300.mq4  3 kb
 
Sergey Efimenko :

Bu özellikleri kullandıysanız

Kullanmasaydım, beni doğru karara itmek için soru sormazdım.

12 periyot ile hesaplama gerekiyorsa 300 bar almanın ne anlamı var??? Bu şekilde gerekli olsa bile, "çünkü" ortalama değerin hesaplanmasında hangi 12 elementin olacağını anlamanız gerekir. Ve dizi indekslemenin yönü ile ilgili ipucu çok doğruydu.

Anlamak için, kağıt üzerinde veya hesap makinesinde, kuyuda veya Excel`de manuel sayma ile deneyler yapın.

 

Bu yüzden cevaplara bakıyorum ve burada sadece zaman kaybettiğimi anlıyorum, sorunun özünü göstermeye çalışıyorum ve yanıt olarak kodun "güzelliğini" alıyorum (elbette teşekkür ederim, ancak önerilen kod yazılmıştır) birkaç dakika içinde yalnızca sorunun özünü görüntülemek için ve okunabilirlik veya başka dönüşümler gerektirmez)...

Ve özellikle mesajımdan önceki cevaptan çok memnun kaldım ... Hangi hesap makinesi, hangi manuel hesaplamalar, hangi indeksleme? Sevgili kullanıcılar, sadece sizin değil başkalarının da zamanını boşa harcamamak için durumun özüne inin. Çiğnenmiş yazılarımı daha dikkatli okuyun, ancak zorsa kısaca cevaplayacağım: dizi indekslemenin yönü her iki durumda da doğrudur, birincil kodda gösterildiği gibi gerekli hesaplamaların ve diğer değişken parametrelerin boyutu, harici değişkenler tarafından ayarlandığında, kendi işlevinizi oluşturma seçeneği yukarıda tartışıldı (ve aslında tek doğru çözüm), ancak yine, bunu yerleşik MT4'ten almak istiyorum.

Genel olarak, hepinize teşekkür ederim, özetleyeceğim: ya hizmet masası ya da işlev analogları.

 

Ve mesajımdan önce cevabı karalıyorum ...

Eh, eğer çok inatçıysanız, => servis masasına ve orada bu tür soruları sadece can sıkıntısından cevaplıyorlar ve nadiren sıkılıyorlar.

Peki, tekrar deneyeceğim...

iMAOnArray() sizin durumunuzda 300 çubuk alır ve 300'den son 12 çubuğun ortalamasını hesaplar. İlk 12 çubuğun ortalamasını almak için dizi indekslemeyi tersine çevirmeniz gerekir , ArraySetAsSeries(BufferMA, false); veya sadece 12 bar alın.

BufferMA[i]= iMAOnArray (Buffer, 12 , 12 , 0 , MODE_SMA ,i);

Böylece, nasıl çalıştığını, nasıl kullanılacağını anlamak, anlamak yerine, onun çalışmadığını veya doğru çalışmadığını beyan ettiğiniz ortaya çıktı. Ve bu senin için doğru değil...

Kodun güzelliği hakkında daha fazla bilgi: Her şey tek satırda yazıldığında birinin kodunuzu okurken gözlerini kırmasının ilginç olduğunu düşünüyor musunuz??? Yanılıyorsun. Şahsen ben okumadım. Davulcuya, herkesi göndermek için günde birkaç kez sabrı için teşekkürler ... benim göndereceğim yere değil.

 

Çok "detaylı" cevap vermek istedim ama sonra mesajları tekrar okuduktan sonra cevabımı sildim ve sonunda burada sadece zaman kaybettiğimi fark ettim, aynı şeyi birkaç kez farklı kelimelerle açıklayarak ...

PS Hepinize teşekkür ederim ve "Barabashka"ya (Vladimir) gerçekten teşekkür ederim, iyi iş çıkardı, ancak tüm bu durum emeğine değmezdi, eğer bunu yapmak zor değilse, ona daha da minnettar olacağım, ekran Bir öncekinin anahtarında, üçüncü seçeneği ekleyerek ve indeksleme yönünü değiştirerek tavsiyeye uyursanız ne olacağını gösterin. Fonksiyon meselesine bir son vermek için.

 
Sergey Efimenko :

Çok "detaylı" cevap vermek istedim ama sonra mesajları tekrar okuduktan sonra cevabımı sildim ve sonunda burada sadece zaman kaybettiğimi fark ettim, aynı şeyi birkaç kez farklı kelimelerle açıklayarak ...

PS Hepinize teşekkür ederim ve "Barabashka"ya (Vladimir) gerçekten teşekkür ederim, iyi iş çıkardı, ancak tüm bu durum emeğine değmezdi, eğer bunu yapmak zor değilse, ona daha da minnettar olacağım, ekran Bir öncekinin anahtarında, üçüncü seçeneği ekleyerek ve indeksleme yönünü değiştirerek tavsiyeye uyursanız ne olacağını gösterin. Fonksiyon meselesine bir son vermek için.

Seçenek 3:

 //+------------------------------------------------------------------+
//|                                         Test300AsSeriesFalse.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link        "https://www.mql5.com"
#property version    "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 clrYellow
#property indicator_color2 clrGreen
#property indicator_color3 clrRed
double Buffer[];
double BufferMA[];
double BufferBMA[];
bool firstrun= true ;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit ()
  {
//--- indicator buffers mapping
   firstrun= true ;
   SetIndexBuffer ( 0 ,Buffer, INDICATOR_DATA );
   SetIndexBuffer ( 1 ,BufferMA, INDICATOR_DATA );
   SetIndexBuffer ( 2 ,BufferBMA, INDICATOR_DATA );
//---
   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[])
  {
//---
   ArraySetAsSeries (open, false );
//---
   int i,limit;
   limit=rates_total-prev_calculated- 1 ;
   if (prev_calculated== 0 )
     {
       ArrayInitialize (Buffer,open[rates_total- 1 ]);
       ArrayInitialize (BufferMA,open[rates_total- 1 ]);
       ArrayInitialize (BufferBMA,open[rates_total- 1 ]);
     }
   for (i=limit; i>= 0 ; i--)
     {
      Buffer[i]=open[i];
      BufferMA[i]= iMAOnArray (Buffer, 300 , 12 , 0 , MODE_SMA ,i);
      BufferBMA[i]= iBandsOnArray (Buffer, 300 , 12 , 2 , 0 , MODE_MAIN ,i);
     }
   return (rates_total);
  }
//+------------------------------------------------------------------+

Ve genel sonuç:

Seçenek 1, 2 ve 3

Dosyalar:
 

Vladimir yok. Biraz öyle değil.

Bu durumda, ArraySetAsSeries(array, false); iMAOnArray() öğesinin dikkate alındığı üç yüz öğeden oluşan bir diziye uygulanır. Ancak bunun için dizi doldurma döngüsü yerine CopyOpen() kullanmak daha iyidir.

Anladığım kadarıyla, bu seçenek daha iyi olurdu

   for (i=limit; i>= 0 ; i--)
     {
      Buffer[i]=open[i];
      BufferMA[i]= iMAOnArray (Buffer, 12 , 12 , 0 , MODE_SMA ,i);
      BufferBMA[i]= iBandsOnArray (Buffer, 12 , 12 , 2 , 0 , MODE_MAIN ,i);
     }