"Bir Göstergenin Diğerine Uygulanması" makalesi için tartışma

 

Yeni makale Bir Göstergenin Diğerine Uygulanması yayınlandı:

OnCalculate() fonksiyon çağrısının kısa biçimini kullanan bir gösterge yazarken, bir göstergenin yalnızca fiyat verileriyle değil, aynı zamanda başka bir göstergenin verileriyle de hesaplanabileceği gerçeğini kaçırabilirsiniz. Diğer göstergelerin verilerine doğru uygulanması için bir göstergeyi geliştirmek ister misiniz? Bu makalede, bu tür bir değişiklik için gereken tüm adımları gözden geçireceğiz.

Yazar: MetaQuotes

 

Bir başka güzel makale için teşekkürler. Geleneksel olarak, MQL Topluluğu makaleleri benim için lise sonrası eğitim almanın bir yolu haline geldi (yani dahili MQL editör kılavuzu)

Bu noktada, kodda küçük bir hata fark ettim. Yazarın fikrine göre

//--- price[] değerlerinin tek seferlik çıktısı için bayrak

değişken

   bool printed=false;

değişkeni OnCalculate() işlevinin dışına taşınmalıdır, aksi takdirde dizi yazdırma işlemi her olayda gerçekleşecektir.

Burada da bir baskı hatası var

Правило передачи PLOT_DRAW_BEGIN в параметр begin: Значение входного параметра begin в OnCalculate(), при расчетах пользовательского индикатора A на данных другого (базового) индикатора B, всегда равно значению свойства PLOT_DRAW_BEGIN  нулевого графического построения базового индикатора B.

Bu nedenle, 14 periyotlu bir RSI göstergesi (gösterge A) oluşturduysak ve ardından RSI (14) gösterge verileri üzerinde özel göstergemiz Gerçek Güç Endeksini (gösterge B) oluşturduysak, o zaman:

Kural ve mantığa göre, A göstergesi özel TSI'dır ve B (temel) göstergesi RSI'dır.

Документация по MQL5: Основы языка / Функции / Функции обработки событий
Документация по MQL5: Основы языка / Функции / Функции обработки событий
  • www.mql5.com
Основы языка / Функции / Функции обработки событий - Документация по MQL5
 

Bu makale detaylı bilgi içermektedir.

Teşekkürler.

 

Merhaba,

Bu makale gerçekten ilginç ve göstergeleri yönetmek için yeni fırsatlar sunuyor.

MQL5'te acemi olduğum için, bir göstergeyi diğerine uygulama olasılığını uygulamaya çalıştım. Yalnızca göstergeyi çoğaltan küçük bir kod yazdım.

grafiğin herhangi bir göstergesinde kullanmayı umarak uyarlanabilir bir hareketli ortalama.

Ne yazık ki, göstergeyi başlattığınızda görünen parametreler listesinde "uygula: önceki göstergenin verileri" durumuna sahip değilim.

Kod, başka bir göstergeye uygulama olanağına sahip olmak için nasıl düzenlenmelidir?

İşte benim kodum:

#property indicator_separate_window
#property indicator_minimum             1.3
#property indicator_maximum             1.35
//#property indicator_chart_window
#property indicator_buffers 2
#property indicator_plots   1
//--- dMA'yı çizin
#property indicator_label1  "dAMA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  Red
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1
//--- giriş parametreleri
input int      AMAPeriod=9;
input int      FastEMA=2;
input int      SlowEMA=20;
//--- gösterge tamponları
double         AMABuffer[];
double         dAMABuffer[];

int            h_dAMA;
int            h_AMA;
//+------------------------------------------------------------------+
//| Özel gösterge başlatma işlevi |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- gösterge tamponları eşleme
   SetIndexBuffer(0,dAMABuffer,INDICATOR_DATA);
   SetIndexBuffer(1,AMABuffer,INDICATOR_CALCULATIONS);
   
   
   
   //PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MAPeriod+1);
   
   h_AMA=iAMA(_Symbol,PERIOD_CURRENT,AMAPeriod,FastEMA,SlowEMA,0,PRICE_CLOSE);
   if(h_AMA == INVALID_HANDLE)
    {
      Print("AMA indicator initialization error, Code = ", GetLastError());
      return(-1);
    }
   ArraySetAsSeries(AMABuffer,true);
   ArraySetAsSeries(dAMABuffer,true);
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MathMax(AMAPeriod,SlowEMA));
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Özel gösterge yineleme işlevi|
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,    // price[] dizisinin boyutu
                const int prev_calculated,// önceki çağrıda işlenen çubuk sayısı
                const int begin,          // önemli verilerin nereden başladığı
                const double &price[]     // hesaplama için dizi
                )
  {
   
   if(BarsCalculated(h_AMA)<rates_total) return(0);
//--- tüm verileri kopyalayamayız
   int to_copy;
   if(prev_calculated>rates_total || prev_calculated<=0) 
     {
      to_copy=rates_total;
      if(CopyBuffer(h_AMA,0,0,to_copy,AMABuffer)<=0) return(0);
      for (int i=0;i<to_copy-MathMax(AMAPeriod,SlowEMA);i++)
          {
            dAMABuffer[i]=AMABuffer[i];
          }
     }
   else
     {
      to_copy=rates_total-prev_calculated+MathMax(AMAPeriod,SlowEMA)-1;
      //--- son değer her zaman kopyalanır
      to_copy++;
      if(CopyBuffer(h_AMA,0,0,to_copy,AMABuffer)<=0) return(0); 
      for (int i=0;i<to_copy;i++)
         {
            dAMABuffer[i]=AMABuffer[i];
         }
     }
//--- kopyalamayı dene
   
   Print(dAMABuffer[0]); //sonuna kadar gidip gitmediğimizi görmek için
//--- sonraki çağrı için prev_calculated değerini döndürür
//---
//--- sonraki çağrı için prev_calculated değerini döndürür
   return(rates_total);
  }
//+------------------------------------------------------------------+
 

Merhaba,

Sorunu anladım: yalnızca aynı pencerede bulunan bir göstergeyi diğerine uygulayabiliyorsunuz.

Bir göstergeyi (ve ayrı bir pencerede görüntülemek için) ana pencerede bulunan başka bir göstergeye nasıl uygulayacağınız konusunda bir fikriniz var mı?

Teşekkürler

En iyiler

 

Programlı olarak (örneğin iCustom aracılığıyla) bir gösterge oluşturma ve ona girdi olarak başka bir göstergeden veri almasını söyleme imkanı var mı? Ya da daha da iyisi, ona üzerine inşa edilmesi gereken doğrudan bir veri dizisi vermek.

 
ds2:

Programlı olarak (örneğin iCustom aracılığıyla) bir gösterge oluşturma ve ona girdi olarak başka bir göstergeden veri almasını söyleme imkanı var mı? Ya da daha da iyisi, ona doğrudan üzerine inşa edilmesi gereken bir veri dizisi vermek.

iCustom fonksiyonuna bakın:

Göstergede ilk çağrı şekli kullanılırsa, "Parametreler" sekmesinde özel bir gösterge başlatırken ek olarak hangi veriler üzerinde hesaplanacağını belirtebilirsiniz. "Uygula" parametresi açıkça seçilmezse, varsayılan olarak hesaplama "Kapanış" değerlerine göre gerçekleştirilir.

Bir mql5-programından özel bir gösterge çağırırken, Applied_Price parametresi veya başka bir göstergenin tanıtıcısı, özel gösterge tarafından sağlanan tüm giriş değişkenlerinden sonra en son aktarılmalıdır.

 

Merhaba,

Bu çok güzel bir makale ancak bazı sorularım var.

1. Yalnızca OnCalculate () işlev çağrısının kısa biçimini kullanan gösterg eler başka bir göstergeye uygulanabilir mi yoksaOnCalculate () işlev çağrısının uzun biçimini kullanan göstergeler de uygulanabilir mi? Eğer öyleyse,OnCalculate() fonksiyon çağrısının uzun formuna sahip bir gösterge başka bir göstergeye uygulanabilir mi?

2. Bir göstergeyi diğerine uygulamak (RSI üzerinden TSI) bazı görüntüleme sorunları yaratır (ekteki resme bakın). RSI 0'dan 100'e kadar çizilirken, ikinci gösterge (TSI) da 0'ın altında değerlere sahip, grafikte görünmeyen değerler. Sorun nedir ve grafik neden her iki göstergeyi de doğru şekilde görüntülemek için düzgün bir şekilde ayarlanmıyor. Bu sorunu çözebilir miyiz yoksa bu bir MetaTrader hatası mı?

Dosyalar:
RSIcTSI.png  32 kb
 
Rosh:

Bir göstergeden bir gösterge oluşturmaya karar verdim ve bir karışıklıkla karşılaştım.

Her iki gösterge de temel üzerine inşa edilmiştir

int OnCalculate (const int rates_total,      // price[] dizi boyutu
                 const int prev_calculated,  // önceki çağrıda işlenen çubuklar
                 const int begin,            // anlamlı verilerin başladığı dizin в массиве price[]
                 const double& price[]       // hesaplama için dizi
   );

Buna göre, kullanıcı parametrelerdeki applied_price alanını ayarlama yeteneğine sahiptir.

Benim zorluğum, uygulanan_fiyat alanının dahili göstergeye (harici göstergenin oluşturulduğu) nasıl aktarılacağıdır?

En basit çözüm, bir giriş yapmak ve kullanıcıyı applied_price girişi ile applied_price parametresinin aynı olması gerektiği konusunda uyarmaktır, ancak bu biraz çarpıktır.

 

OnCalculate() için örneğe baktınız mı?

Для получения значений пользовательского индикатора из других mql5-программ используется функция iCustom(), возвращающая хэндл индикатора для последующих операций. При этом также можно указать необходимый массив  price[] или хэндл другого индикатора. Этот параметр должен передаваться последним в списке  входных переменных пользовательского индикатора.
 
Пример:

void OnStart()
  {
//---
   string terminal_path=StatusInfoString(STATUS_TERMINAL_PATH);
   int handle_customMA=iCustom(Symbol(),PERIOD_CURRENT, "Custom Moving Average",13,0, MODE_EMA,PRICE_TYPICAL);
   if(handle_customMA>0)
      Print("handle_customMA = ",handle_customMA);
   else
      Print("Cannot open or not EX5 file '"+terminal_path+"\\MQL5\\Indicators\\"+"Custom Moving Average.ex5'");
  }

Bu örnekte, aktarılan son parametre PRICE_TYPICAL değeridir ( ENUM_APPLIED_PRICE numaralandırmasından), bu da özel göstergenin (High+Low+Close)/3 olarak elde edilen tipik fiyatlarla oluşturulacağını gösterir. Parametre belirtilmezse, gösterge PRICE_CLOSE değerlerine göre, yani her çubuğun kapanış fiyatlarına göre oluşturulur.

 
Rosh:

OnCalculate() için örneğe baktınız mı?


Evet, söyledim,

int handle_customMA=iCustom(Symbol(),PERIOD_CURRENT, "Custom Moving Average",13,0, MODE_EMA,PRICE_TYPICAL);

applied_price iCustom çağrıldığında açıkça belirtilir, ancak iCustom'ın çağrıldığı göstergede nereden alınır?

Çünkü kullanıcı bunu parametrelerde ayarlar, girdilerde değil.

int OnInit()
  {
//--- gösterge tamponları eşleme
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
   hndl=iCustom(_Symbol,_Period,"MyInd",param_ind,???? вот тут нужно указать аплиед_прайс который будет задавать пользователь);
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Özel gösterge yineleme işlevi |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
{
 //...
 return(rates_total);
}

Not: İşin püf noktası, kullanıcının applied_price parametresini bir kez ayarlamış olması ve artık rahatsız etmemesi, bu değerin tüm çağrı piramidinden geçmesidir.