En Düşük ve En Yüksek Fonksiyonlar Ne Getirir?

 
Sevgili Metatrader geliştiricileri!.

En Düşük ve En Yüksek işlevler ne döndürür?
Bu soruyu neden soruyorum? Bu işlevlerin açıklaması kafa karıştırıcıdır. Metatrader ile birlikte verilen ZigZag'ın neden düzgün çalışmadığını analiz ederken, yukarıdaki fonksiyonların hiçbir şey döndürmediği gerçeğiyle karşılaştım. Ya da belki de kafa karıştırıcı açıklama nedeniyle kötüye kullanılıyorlar? Bu forum sayfasında, 77. sayfada Elliott dalga teorisine dayalı Ticaret stratejisi başlığında bu sorun açıklanmıştır. Anlamaya çalışıyorum, belki ZigZag algoritması yanlıştır. Ancak her şey bu işlevlerin çalışmasına bağlıdır.

Diğer göstergelerde de bu işlevlerle ilgili sorunlar gözlemledim. Ama şu anda - ZigZag'da.

Lütfen açıkla.
 
Geçmişteki mevcut olandan en yüksek ve en düşük N çubuk olan çubuğun sayısını döndürürler. Bu durumda, iki değer eşitse (bu örnekte iki çubuk ekstremumdur), daha önce gelen çubuğun sayısı (eski olan) her zaman döndürülür.

ZigZag algoritması (MT4'te standart olarak bulunur), bir çubuğun aynı anda hem yüksek hem de düşük olabileceği (dış çubuk) durumu hesaba katmaz.
 
Rosh, bu anlaşılabilir. Dalga analizi başlığında bahsettiğim satırları zikzak metnine eklemeye çalışın. Ve ne olduğunu görün. Ve çöp çıkıyor. Bu nedenle, soru ortaya çıktı.

Teori ile pratikten ayrılmaya başlamadığı sürece her şey açıktır. Hatalar oluşursa, sonuna kadar gitmeniz gerekir. Ve hataların nereden geldiğini bulun.
 
Rosh, bu anlaşılabilir. Dalga analizi başlığında bahsettiğim satırları zikzak metnine eklemeye çalışın. Ve ne olduğunu görün. Ve çöp çıkıyor. Bu nedenle, soru ortaya çıktı.


Oniks üzerindeki o sayfaya baktım ve karşılaştırmak için standart Zigzag'ı açtım. Kodlar anlamak için farklıdır - ZigZag sürümünüzü bulmanız, iyice ayrıştırmanız ve ancak o zaman bir şeyler söylemeniz gerekir. Bu nedenle cevap veremiyorum.

Ve evet sayfanızda gösterilen kodda değerlerin yazılması konusunda anlaşmazlıklar var ama belki de öyle olmalı, bunu söylemek zor. Bazen sürünen değerlerle bu tür göstergeler yapıyorum, bir kanal gibi bir şey çıkıyor, ancak tarihe yatmıyor.
 
Rosh, işte codebase.mql.com adresinden zikzak kodu

//+------------------------------------------- --------------------+
//| Özel Hareketli Ortalama.mq4 |
//| Telif Hakkı © 2005, MetaQuotes Yazılım A.Ş. |
//| https://www.metaquotes.net/ |
//+------------------------------------------- --------------------+
#property telif hakkı "Telif hakkı © 2005, MetaQuotes Software Corp."
#özellik bağlantısı https://www.metaquotes.net/

#özellik göstergesi_chart_window
#özellik göstergesi_tamponları 1
#özellik göstergesi_renk1 Kırmızı
//---- gösterge parametreleri
dış int DışDepth=12;
harici int ExtDeviation=5;
harici int ExtBackstep=3;
//---- gösterge arabellekleri
çift ExtMapBuffer[];
çift ExtMapBuffer2[];

//+------------------------------------------- --------------------+
//| özel gösterge başlatma işlevi |
//+------------------------------------------- --------------------+
int init()
{
Gösterge Tamponları(2);
//---- çizim ayarları
SetIndexStyle(0,DRAW_SECTION);
//---- gösterge arabellek eşlemesi
SetIndexBuffer(0,ExtMapBuffer);
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexEmptyValue(0,0.0);
//---- gösterge kısa adı
IndicatorShortName("ZigZag("+ExtDepth+","+ExtDeviation+","+ExtBackstep+")");
//---- başlatma tamamlandı
dönüş(0);
}
//+------------------------------------------- --------------------+
//| |
//+------------------------------------------- --------------------+
int başlangıç()
{
int shift, geri, son yüksek konum, son düşük konum;
çift değer, res;
çift kıvrım, kıvrım, son, son;

for(shift=Bars-ExtDepth; shift>=0; shift--)
{
val=Düşük[En Düşük(NULL,0,MODE_LOW,ExtDepth,shift)];
if(val==lastlow) val=0.0;
başka
{
lastlow=val;
if((Low[shift]-val)>(ExtDeviation*Point)) val=0.0;
başka
{
for(geri=1; geri<=ExtBackstep; geri++)
{
res=ExtMapBuffer[shift+back];
if((res!=0)&&(res>val)) ExtMapBuffer[shift+back]=0.0;
}
}
}
******ExtMapBuffer[shift]=val;
//--- yüksek
val=Yüksek[En yüksek(NULL,0,MODE_HIGH,ExtDepth,shift)];
if(val==sonyüksek) val=0.0;
başka
{
sonyüksek=val;
if((val-High[shift])>(ExtSapma*Nokta)) val=0.0;
başka
{
for(geri=1; geri<=ExtBackstep; geri++)
{
res=ExtMapBuffer2[shift+back];
if((res!=0)&&(res<val)) ExtMapBuffer2[shift+back]=0.0;
}
}
}
***** ExtMapBuffer2[shift]=val;
}


=============================

Hatanın olduğu kısım burası.Dalga analizi ile ilgili bölümün 77. sayfasında bahsettiğim yerleri yıldızla işaretledim. Bu kodun benim verdiğimden farkı nedir? Bu standart koddur.

Şimdi bu konunun ikinci mesajındaki sözlerini alıntılıyorum.

Roş 18.10.06 10:14

Geçmişteki mevcut olandan en yüksek ve en düşük N çubuk olan çubuğun sayısını döndürürler. Bu durumda, iki değer eşitse (bu örnekte iki çubuk ekstremumdur), daha önce gelen çubuğun sayısı (eski olan) her zaman döndürülür.

ZigZag algoritması (MT4'te standart olarak bulunur), bir çubuğun aynı anda hem yüksek hem de düşük olabileceği (dış çubuk) durumu hesaba katmaz.
=======================
Kodda bir satır var: val=Yüksek[Yüksek(NULL,0,MODE_HIGH,ExtDepth,shift)];
Köşeli parantez içinde çubuğun numarası var... peki, cevabınızda çubuğun numarasının ne olduğu yazıyor.

Ayrıca satırda: ExtMapBuffer[shift]=val; - neyimiz var? Daha fazla açıklamalı mıyım?

İlk olarak, gösterge tamponunun indeksi, val değerini aldığımız çubuğun indeksine eşit olmalıdır. Aksi takdirde bir uyumsuzluk olacaktır. Aslında sahip olduğumuz şey, zikzak havada bir kırılma olduğunu gördüğümüzde.

Rosh, cevaptan kaçma. Sizin beyniniz bir zikzaktır. Anlayalım. Kodda birçok hata var. Yazdıklarımı dikkatlice analiz ederseniz, bariz hatalar göreceksiniz.

Ama asıl mesele bu değil. Sadece bu hatalar olsaydı, başlığın olduğu soruyu sormazdım.
 
Bir kez daha En Düşük ve En Yüksek işlevler hakkında.

Bir önceki yazımda zikzak kodundaki bir hatadan bahsetmiştim.

Ana hata.

ExtDepth çubuklarının boyutu alanında, en yüksek veya en düşük en düşük olan çubuk aranır. Arama SHIFT çubuğundan yapılır. Roche, aşağıdaki işlev tanımını verdi: N çubuk içindeki en yüksek ve en düşük çubuk sayısı, geçerli olandan geçmişin derinliğine döndürülür. Ancak mevcut çubuğun ne olduğuna dair bir tanım yok. Geçerli çubuk, sıfır çubuk veya kaydırma numaralı bir çubuktur. Verilen ZigZag koduna bakılırsa, mevcut çubuk, vardiya numarasına sahip çubuk olarak anlaşılmalıdır.

Vardiya numarası ile çubuktan sayarak çubuğun ExtDepth bölümündeki çubuk numarasını bulduğumuzu varsayalım. Ve bu çubuğun mutlaka bir vardiya numarası olmayacaktır. Ancak bulunan çubuğun, kaydırma numarası ile çubuktan farklı olan ekstremumunun değerini, kaydırma numarasının altındaki gösterge tamponuna koyduk: ExtMapBuffer[shift]=val. Buradan zikzakta havada asılı kırıklar elde edilir. MT'den zikzak ile çalışmayı deneyen herkes gördü.

Bu ana hatadır. Ancak bu hatayı düzeltmek kolaydır. Ve sormaya değmezdi.

Bu hatayı kaldırmaya başladığınızda, şu soru ortaya çıkar: çubukta En Düşük ve En Yüksek işlevleri istenen ekstremumu hangi sayı ile buldu? Burada hiçbir mantık yardımcı olmuyor. Bu çubuğun sayısını ne kadar hesaplamaya çalışsam da hiçbir şey olmadı.

Bu nedenle, soru geliştiricilere yönelikti.

Ama Rosh'un soruyu yanıtlamaya başlamasına sevindim. Bu, uzun bir süre düzenledikten sonra MT'nin teslimatına dahil olan zikzak kullanıyoruz.

Sevgili geliştiriciler, lütfen sorulan sorulara dikkat edin. Sorular ciddi. Pek çok gösterge, MT'nin teslimatına dahil olan zikzak kullanır. Zigzag çalışmasıyla ilgili şikayetlerin sayısını sayamazsınız.
Hataların açıklamasını verdim. İyi haber şu ki, hataların düzeltilmesi gerekiyor. Hata düzeltmelerini görmezden gelmek, bir şirketin itibarına zarar verir. Ve bu iyi değil. Kimsenin buna ihtiyacı yok.
 
...soru ortaya çıkıyor, çubukta En Düşük ve En Yüksek fonksiyonların istenen ekstremumu hangi sayı ile bulduğu? Burada hiçbir mantık yardımcı olmuyor. Bu çubuğun sayısını ne kadar hesaplamaya çalışsam da hiçbir şey olmadı.
Teoride, bar indeksi = En yüksek(NULL,0,MODE_HIGH,ExtDepth,shift)

Onlar. ExtMapBuffer2 olmalıdır[En yüksek(NULL,0,MODE_HIGH,ExtDepth,shift)]=val;
 
nen, şimdi standart Zig-Zag algoritmasına baktım - sizin verdiğinizden farklı bir algoritma daha var:

//+------------------------------------------------------------------+
//|                                                       ZigZag.mq4 |
//|                      Copyright © 2005, MetaQuotes Software Corp. |
//|                                       http://www.metaquotes.net/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2005, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net/"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
//---- indicator parameters
extern int ExtDepth=12;
extern int ExtDeviation=5;
extern int ExtBackstep=3;
//---- indicator buffers
double ExtMapBuffer[];
double ExtLowBuffer[];
double ExtHighBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
   IndicatorBuffers(3);
//---- drawing settings
   SetIndexStyle(0,DRAW_SECTION);
//---- indicator buffers mapping
   SetIndexBuffer(0,ExtMapBuffer);
   SetIndexBuffer(1,ExtLowBuffer);
   SetIndexBuffer(2,ExtHighBuffer);
   SetIndexEmptyValue(0,0.0);
//---- indicator short name
   IndicatorShortName("ZigZag("+ExtDepth+","+ExtDeviation+","+ExtBackstep+")");
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int start()
  {
   int    shift, back,lasthighpos,lastlowpos,index;
   double val,res;
   double curlow,curhigh,lasthigh,lastlow;
//----
   for(shift=Bars-ExtDepth; shift>=0; shift--)
     {
      index=Lowest(NULL,0,MODE_LOW,ExtDepth,shift);
      val=Low[index];
      if(val==lastlow) val=0.0;
      else 
        { 
         lastlow=val; 
         if((Low[shift]-val)>(ExtDeviation*Point)) val=0.0;
         else
           {
            for(back=1; back<=ExtBackstep; back++)
              {
               res=ExtLowBuffer[shift+back];
               if((res!=0)&&(res>val)) ExtLowBuffer[shift+back]=0.0; 
              }
           }
        } 
      ExtLowBuffer[shift]=0.0;
      if(val!=0.0) ExtLowBuffer[index]=val;
      //--- high
      index=Highest(NULL,0,MODE_HIGH,ExtDepth,shift);
      val=High[index];
      if(val==lasthigh) val=0.0;
      else 
        {
         lasthigh=val;
         if((val-High[shift])>(ExtDeviation*Point)) val=0.0;
         else
           {
            for(back=1; back<=ExtBackstep; back++)
              {
               res=ExtHighBuffer[shift+back];
               if((res!=0)&&(res<val)) ExtHighBuffer[shift+back]=0.0; 
              } 
           }
        }
      ExtHighBuffer[shift]=0.0;
      if(val!=0.0) ExtHighBuffer[index]=val;
     }
//---- final cutting 
   lasthigh=-1; lasthighpos=-1;
   lastlow=-1;  lastlowpos=-1;

   for(shift=Bars-ExtDepth; shift>=0; shift--)
     {
      curlow=ExtLowBuffer[shift];
      curhigh=ExtHighBuffer[shift];
      if(curlow==0 && curhigh==0) continue;
      //---
      if(curhigh!=0)
        {
         if(lasthigh>0) 
           {
            if(lasthigh<curhigh) ExtHighBuffer[lasthighpos]=0;
            else ExtHighBuffer[shift]=0;
           }
         //---
         if(lasthigh<curhigh || lasthigh<0)
           {
            lasthigh=curhigh;
            lasthighpos=shift;
           }
         lastlow=-1;
        }
      //----
      if(curlow!=0)
        {
         if(lastlow>0)
           {
            if(lastlow>curlow) ExtLowBuffer[lastlowpos]=0;
            else ExtLowBuffer[shift]=0;
           }
         //---
         if((curlow<lastlow)||(lastlow<0))
           {
            lastlow=curlow;
            lastlowpos=shift;
           } 
         lasthigh=-1;
        }
     }
//---- merge 2 buffers
   lasthighpos=-1;
   lastlowpos=-1;
   for(shift=Bars-1; shift>=0; shift--)
     {
      if(shift>=Bars-ExtDepth) ExtMapBuffer[shift]=0.0;
      else
        {
         curlow=ExtLowBuffer[shift];
         curhigh=ExtHighBuffer[shift];
         //----
         res=0;
         if(curlow!=0)
           {
            if(lastlowpos==-1)
              {
               res=curlow;
               lastlowpos=shift;
              }
            else
              {
               if(lasthighpos!=-1 && lastlowpos>lasthighpos)
                 {
                  res=curlow;
                  lastlowpos=shift;
                 }
              }
           }
         if(curhigh!=0)
           {
            if(lasthighpos==-1)
              {
               res=curhigh;
               lasthighpos=shift;
              }
            else
              {
               if(lastlowpos!=-1 && lasthighpos>lastlowpos)
                 {
                  res=curhigh;
                  lasthighpos=shift;
                 }
              }
           }
         //----
         ExtMapBuffer[shift]=res;
        }
     }
  }
//+------------------------------------------------------------------+



Burada her şey doğru görünüyor - ve dizin kaydedilir ve değer dizinin istenen öğesine yazılır. Bu algoritmayı geliştirelim.

 
nen , pardon, aynı En Düşük ve En Yüksek bulan kısa bir kod yazmak daha kolay değil mi? Bu işlevleri hiç kullanmadım, çünkü ekstremumlarda ihtiyacım olan verileri basit bir kısa kodla aldım, çünkü muhtemelen standart işlevlerden daha hızlı çalışacak. Bana öyle geliyor ki, bunları yalnızca başka bir zaman diliminden veri almanız gerekiyorsa kullanmak mantıklı.
 
Komposter doğru. Bakın o zaman nerede yazıyor. Hangi indeks ile gösterge arabelleğine .
Vladislav, kodu codebase.mql.com'dan getirdim ve aynısı bende var. Kodunuzu göndermeye çalışacağım. Bakalım ne olacak.
Candid, daha kolay olabileceğine katılıyorum. Ancak farklı bir zaman diliminde çalışmak için bu işlevlere ihtiyacım olacak.
Neden: