English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
MQL5'te olay işleme: MA dönemini anında değiştirme

MQL5'te olay işleme: MA dönemini anında değiştirme

MetaTrader 5Göstergeler | 10 Aralık 2021, 17:14
165 0
Sceptic Philozoff
Sceptic Philozoff

Giriş

Bu kısa makale, MetaQuotes Software Corp. tarafından geliştirilen MetaTrader 5 platformunun yeni MQL5 özelliklerinden birine ayrılmıştır. Belki bu makale biraz gecikmiş olabilir (Eylül-Ekim 2009'da yayınlanmış olmalıydı; o zaman yayınlansaydı tam zamanı olurdu), ancak bu konuda benzer makaleler yoktu. Ayrıca, o zamanlar, olayları göstergelerde işlemek için böyle bir olasılık yoktu.

Bir grafiğe uygulanan basit bir fiyat göstergesine sahip olduğumuzu (bu durumda bu, Hareketli Ortalama, yani MA'dır) ve yumuşatma dönemini değiştirmek istediğimizi hayal edin. MT4 platformunda aşağıdaki seçeneklere sahibiz:

  • MetaEditor'da MA döneminden sorumlu expert giriş parametresini (harici) düzenleyebilir ve ardından kaynak dosyayı derleyebilirsiniz.
  • MetaEditor'a geçmeden, sağda terminal penceresinde göstergenin Özellikler iletişim kutusunu açabilir ve orada ilgili giriş parametresini düzenleyebilirsiniz.
  • Win32 API kitaplığını açabilir, mesaj yakalama işlevlerini bulabilir, ardından klavyeden olaylara yanıt vermesi için gösterge kodunda son ayarlamaları yapabilirsiniz.

Bildiğimiz gibi, minimum çaba gösterme arzusu, ilerlemenin en büyük lokomotifidir. Artık, kullanıcı tarafından başlatılan gösterge olaylarının işlenmesine olanak tanıyan yeni bir MT5 platformu sayesinde, yukarıdaki olasılıkları atlayabilir ve tek bir tuşa basarak gösterge parametrelerini değiştirebiliriz. Bu makale, bu sorun çözümüne ilişkin teknik uygulamayı içermektedir.

Görev ataması ve sorunlar

Denemelerimizde kullanılan gösterge kaynak kodu, İstemci Terminali ile birlikte gönderilir. Değişmeyen kaynak kod dosyası (Custom Moving Average.mq5) bu makalenin sonuna eklenmiştir.

Şimdilik kaynak kodunu ve özellikle orijinal MQL4'üne kıyasla değişiklikleri analiz etmeyeceğiz. Evet, bu, bazı yerlerde önemli ölçüde değişti ve her zaman aşikar değil. Hesaplamanın temel kısmının yeniden yapılandırılmasına ilişkin ilgili açıklamalar forumda ve çevrimiçi yardımda bulunabilir.

Yine de, MQL4'teki göstergenin ana kısmı değişmeden kaldı. Sorunumuzu çözmeye yönelik tüm kod değişikliklerinin en az %80'i, göstergenin hesaba dayalı işlevlerinin "kara kutular" olduğu fikri temel alınarak yapılmıştır.

Başarmak istediğimiz şeyin bir örneği şuna benzerdir. Bu göstergeyi bir grafiğe uyguladığımızı ve belirli bir anda sıfır kaymalı ve 10 dönemli bir üstel MA (EMA) gösterdiğini varsayalım. Amacımız basit MA (SMA) yumuşatma dönemini 3 (en fazla 13) değer artırmak ve 5 çubuk sağa kaydırmaktır. Varsayılan işlem sırası aşağıdaki gibidir:

  • Görüntülenen MA'yı üstelden basite (MA türünü değiştirerek) değiştirmek için TAB tuşuna birkaç kez basın.
  • Basit MA dönemini 3 değer artırmak için klavyenin ana kısmındaki YUKARI ok tuşuna üç kez basın.
  • MA'yı 5 çubuk sağa kaydırmak için sayısal tuş takımındaki YUKARI (8) ok tuşuna 5 kez basın.

İlk ve en açık çözüm, OnChartEvent() işlevini gösterge koduna eklemek ve tuş vuruşu olay işleyicisini yazmaktır. MetaTrader 4 İstemci Terminali yapı 245 ve 246'daki değişikliklerin listesine göre https://www.mql5.com/en/forum/53/page1/#comment_2655,

MetaTrader 5 İstemci Terminali yapı 245 ve 246

MQL5: Expert Advisor'larınkine benzer şekilde özel göstergelerle olay işleme olasılığı eklendi.

Yani, artık göstergeye yeni olay işleyicileri eklemekle ilgili herhangi bir sorunumuz yok. Ancak bunun için hala kodunu biraz değiştirmemiz gerekiyor.

İlk önce, MQL5'te göstergenin harici parametrelerinin durumu değişti: Bunları kodda değiştiremezsiniz. Bunları değiştirmenin tek yolu, İstemci Terminalindeki Özellikler iletişim kutusudur. Genel olarak, onları acilen değiştirmek gerektiğinde bu kısıtlama kolayca atlanır: Harici parametrelerin değerlerini göstergenin yeni genel değişkenlerine kopyalamanız yeterlidir ve tüm hesaplamalar, bu yeni değişkenler aslında göstergenin harici parametreleriymiş gibi yapılır. Diğer taraftan, bu durumda, değerleri yalnızca kullanıcıları yanıltabilecek harici parametrelerin uygulanabilirliği ortadan kalkar. Artık bu parametrelere gerek kalmadı.

Bu nedenle, göstergede herhangi bir harici (giriş) parametre yoktur. Harici parametrelerin rolünü oynayan değişkenler, artık kısaca Terminal Genel Değişkenler veya TGV olacaktır. Göstergenin önceki harici parametrelerinden sorumlu olan TGV'yi görüntülemek isterseniz terminalde F3 tuşuna basmanız yeterlidir. Gösterge parametrelerini kontrol etmek için başka bir basit yol bulamıyorum.

İkincisi (ve bu önemlidir), göstergenin harici parametrelerindeki herhangi bir değişiklikte tüm değerlerini geçmiş boyunca yeniden ve sıfırdan tekrar hesaplamamız gerekir. Diğer bir deyişle, genellikle yalnızca göstergenin ilk başlangıcında yapılan hesaplamaları yapmamız gerekecek. Göstergenin hesaplama optimizasyonu devam ediyor, ancak şimdi daha güç algılanacak hale geliyor.

Değiştirilmiş göstergenin ilk sürümünün birkaç kod parçası aşağıdadır. Tam kod bu makalenin sonuna eklenmiştir.

 

"Standart" sürüm: Standart gösterge kaynak kodundaki değişikliklerin açıklaması

Dış parametreler artık harici değildir; yalnızca genel değişkenler

Göstergenin tüm harici parametreleri giriş değiştiricilerini kaybetti. Genel olarak, onları genel dahi yapamadım ama bunu geleneksel olarak yapmaya karar verdim:

int              MA_Period   = 13;
int              MA_Shift    =  0;
ENUM_MA_METHOD   MA_Method   =  0;
int              Updated     =  0;     /// Indicates whether the indicator has updated after changing it's values

İlk üç seçenek - MA'nın dönemi, ofseti ve türüdür ve dördüncüsü - Güncellendi'dir - MA parametreleri değiştirilirken hesaplama optimizasyonundan sorumludur. Açıklamalar birkaç satır aşağıda verilmiştir.

Sanal anahtar kodları

Sanal anahtarların kodlarını girin:

#define KEY_UP             38
#define KEY_DOWN           40
#define KEY_NUMLOCK_DOWN   98
#define KEY_NUMLOCK_UP    104
#define KEY_TAB             9

Bunlar, "yukarı ok" ve "aşağı ok" tuşlarının kodları, sayısal klavyedeki ("8" ve "2" tuşları) benzer okların yanı sıra SEKME tuşudur. Aynı kodlar (VK_XXX sabitlerinin diğer adlarıyla birlikte) aslında <MT5dir>\MQL5\Include\VirtualKeys.mqh dosyasında mevcuttur fakat bu durumda onu olduğu gibi bırakmaya karar verdim.


Doğrusal ağırlıklı hareketli ortalamayı (LWMA) hesaplayan işlevde küçük kod düzeltmesi

CalculateLWMA() işlevinde küçük bir değişiklik yaptım: Orijinal sürümde weightsum değişkeni, static değiştiricisi kullanılarak bildirildi. Görünüşe göre, geliştiricilerin bunu yapmasının tek nedeni, bu işlevin ilk çağrısında önceden hesaplama ihtiyacıydı. Ayrıca kodda bu değişken değişmeden kalır. Hesaplama ve weightsum değişkeninin kullanımı ile ilgili kısımların açıklamalarla işaretlendiği bu işlevin orijinal kodu şu şekildedir:

void CalculateLWMA(int rates_total,int prev_calculated,int begin,const double &price[])
  {
   int              i,limit;
   static int     weightsum;                       // <-- using weightsum
   double               sum;
//--- first calculation or number of bars was changed
   if(prev_calculated==0)                          // <-- using weightsum
     {
      weightsum=0;                                 // <-- using  weightsum
      limit=InpMAPeriod+begin;                     // <-- using weightsum
      //--- set empty value for first limit bars
      for(i=0;i<limit;i++) ExtLineBuffer[i]=0.0;
      //--- calculate first visible value
      double firstValue=0;
      for(i=begin;i<limit;i++)                     // <-- using weightsum
        {
         int k=i-begin+1;                          // <-- using weightsum
         weightsum+=k;                             // <-- using weightsum
         firstValue+=k*price[i];
        }
      firstValue/=(double)weightsum;
      ExtLineBuffer[limit-1]=firstValue;
     }
   else limit=prev_calculated-1;
//--- main loop
   for(i=limit;i<rates_total;i++)
     {
      sum=0;
      for(int j=0;j<InpMAPeriod;j++) sum+=(InpMAPeriod-j)*price[i-j];
      ExtLineBuffer[i]=sum/weightsum;              // <-- using weightsum
      }
//---
  }

Daha önce, bu değişken oldukça iyi çalışıyordu, ancak "gösterge + advisor" ikilisini çalıştırdığımda (bu makalenin sonunda bahsedilmiştir), bu MA türünde sorunlar çıktı. Bu sorunların temel nedeni, yukarıda açıklanan koşullardan kaynaklanıyordu; yani weightsum, statik değişkendi: MA parametresindeki her değişiklik anında, onu sıfırdan tekrar hesaplamak gerektiği için bu değişken sürekli artıyordu.

weightsum değerini doğrudan ve hemen hesaplamanın en kolay yolu (1'den MA dönemine kadar olan tamsayıların toplamına eşittir - bu amaçla aritmetik dizinin toplamı için basit bir formül vardır) ve aynı zamanda, yaptığım bir statik olarak statüsünü inkar ettim. Şimdi, statik değiştiricisini kullanan önceki weightsum bildirimi yerine, onu onsuz bildiriyoruz, yalnızca "doğru" değerle başlatıyoruz ve böylece "değişken yığını"nın ilk döngüsünü ortadan kaldırıyoruz.

int weightsum = MA_Period *( MA_Period + 1 ) / 2;

Artık her şey düzgün işliyor.


OnCalculate() işleyici olarak işlev görür

OnCalculate() işlevinde bir çok değişiklik yapmak zorunda kaldım ve bu nedenle burada kodunu tamamen alıntılıyorum.

int OnCalculate(const int rates_total,
                const int prev_calculated,            /// Mathemat: full recalculation!
                const int begin,                      /// Mathemat: full recalculation!
                const double &price[])
  {
//--- check for bars count
   if(rates_total<MA_Period-1+begin)
      return(0);// not enough bars for calculation
//--- first calculation or number of bars was changed
   if(prev_calculated==0)
      ArrayInitialize(LineBuffer,0);
//--- sets first bar from what index will be draw
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,MA_Period-1+begin);

//--- calculation (Mthmt - optimized by Mathemat)

   if( GlobalVariableGet( "Updated" ) == 1 )
   {
      if(MA_Method==MODE_EMA)  CalculateEMA(       rates_total,prev_calculated,begin,price);
      if(MA_Method==MODE_LWMA) CalculateLWMA_Mthmt(rates_total,prev_calculated,begin,price);
      if(MA_Method==MODE_SMMA) CalculateSmoothedMA(rates_total,prev_calculated,begin,price);
      if(MA_Method==MODE_SMA)  CalculateSimpleMA(  rates_total,prev_calculated,begin,price);
   }
   else
   {
      OnInit( );                 /// Mthmt
      if(MA_Method==MODE_EMA)  CalculateEMA(       rates_total,0,0,price);
      if(MA_Method==MODE_LWMA) CalculateLWMA_Mthmt(rates_total,0,0,price);
      if(MA_Method==MODE_SMMA) CalculateSmoothedMA(rates_total,0,0,price);
      if(MA_Method==MODE_SMA)  CalculateSimpleMA(  rates_total,0,0,price);
      GlobalVariableSet( "Updated", 1 );
      Updated = 1;
   }
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

Ana değişiklik, göstergenin "sıfırdan" eksiksiz hesaplanması için algılanan gereklilikle ilgilidir: Bir kullanıcının klavye manipülasyonunun MA dönemini 13'ten 14'e değiştirmesi halinde, hesaplamalarının önceki tüm optimizasyonlarının zaten işe yaramaz olduğu aşikardır; MA'yı tekrar hesaplamamız gerekiyor. Bu, Güncellendi değişkeni 0 değerine sahip olduğunda meydana gelir (kısayol tuşuna basıldıktan sonra TGV değişti fakat göstergeyi yeniden çizen tick henüz ortaya çıkmadı).

Ancak, ayrıca, önceden açıkça OnInit() işlevini çağırmamız gerekiyordu; zira bir imleç satırın üzerine geldiğinde görüntülenecek olan gösterge kısa adını değiştirmemiz gerekiyordu. İlk MA hesaplamasından sonra Güncellendi TGV, 1 olarak ayarlanır ve bu, optimize edilmiş gösterge hesaplamasının yolunu açar - siz tekrar bazı göstergelerin parametrelerini anında değiştirmek istemeyinceye kadar.


OnChartEvent() işleyicisi

OnChartEvent() işleyicisinin basit bir kodu aşağıda verilmiştir:

void OnChartEvent( const int          id,
                   const long    &lparam,
                   const double  &dparam,
                   const string  &sparam )
{
   if( id == CHARTEVENT_KEYDOWN )
      switch( lparam )
      {
         case( KEY_TAB          ):  changeTerminalGlobalVar( "MA_Method",  1 ); 
                                    GlobalVariableSet( "Updated",  0 );
                                    Updated = 0;
                                    break;
         
         case( KEY_UP           ):  changeTerminalGlobalVar( "MA_Period",  1 ); 
                                    GlobalVariableSet( "Updated",  0 );
                                    Updated = 0;
                                    break;
         case( KEY_DOWN         ):  changeTerminalGlobalVar( "MA_Period", -1 ); 
                                    GlobalVariableSet( "Updated",  0 );
                                    Updated = 0;
                                    break;
         
         case( KEY_NUMLOCK_UP   ):  changeTerminalGlobalVar( "MA_Shift",   1 ); 
                                    GlobalVariableSet( "Updated",  0 );
                                    Updated = 0;
                                    break;
         case( KEY_NUMLOCK_DOWN ):  changeTerminalGlobalVar( "MA_Shift",  -1 ); 
                                    GlobalVariableSet( "Updated",  0 );
                                    Updated = 0;
                                    break;
      }
      
      return;
}//+------------------------------------------------------------------+      

İşleyici şu şekilde çalışır: Kısayol tuşuna bastığınızda, sanal kodu tanımlanır ve ardından changeTerminalGlobalVar() yardımcı işlevi başlatılır ve istenen TGV'yi doğru şekilde değiştirir. Bunun ardından, Güncellendi bayrağı sıfırlanır, tick beklenir; bu tick, OnCalculate() işlevini başlatacak ve göstergeyi "sıfırdan" yeniden çizecektir.


TGV'yi "doğru şekilde" değiştiren yardımcı işlev

Ve son olarak, OnChartEvent() işleyicisinde kullanılan changeTerminalGlobalVar() işlevinin kodu:

void changeTerminalGlobalVar( string name, int dir = 0 )
{
   int var = GlobalVariableGet( name );
   int newparam = var + dir;
   if( name == "MA_Period" )
   {
      if( newparam > 0 )       /// Possible period is valid for MA
      {
         GlobalVariableSet( name, newparam ); 
         MA_Period = newparam;     /// Don't forget to change the global variable    
      }   
      else                       /// we do not change the period, because MA period is equal to 1 minimum
      {   
         GlobalVariableSet( name, 1 );     
         MA_Period = 1;     /// Don't forget to change the global variable 
      }   
   }   
      
   if( name == "MA_Method" )    /// Here when you call the 'dir' it is always equal to 1, the dir value is not important    
   {
      newparam = ( var + 1 ) % 4;
      GlobalVariableSet( name, newparam );  
      MA_Method = newparam;
   }      

   if( name == "MA_Shift" )
   {
      GlobalVariableSet( name, newparam );     
      MA_Shift = newparam;
   }      

   ChartRedraw( );
   return;
}//+------------------------------------------------------------------+

Bu işlevin temel amacı, "fiziksel sınırlamaları" dikkate alarak yeni MA parametrelerinin doğru hesaplanmasıdır. Açıkçası, MA dönemini 1'den küçük yapamayız, MA kayması rastgele olabilir, ancak MA türü 0 ile 3 aralığındaki sayıdır; bu, ENUM_MA_METHOD numaralandırmasındaki koşullu üye sayısına karşılık gelir.

 

Kontrol etme. Çalışıyor, ancak "C sınıfında". Ne yapabiliriz?

Peki, o halde göstergemizi grafiğe uygulayalım ve MA parametrelerini değiştiren kısayol tuşlarına ara sıra basmaya başlayalım. Evet, her şey düzgün çalışıyor, ancak hoş olmayan bir durum var: TGV'ler hemen değişiyor (bunu TGV'yi F3 tuşuyla çağırarak kontrol edebilirsiniz), ancak MA her zaman hemen değil, yalnızca yeni tick ortaya çıktığında yeniden çiziyor. Aktif tick akışı olan bir Amerikan seansımız varsa gecikmeyi neredeyse hiç fark edemeyiz. Ancak geceleyin, sessiz bir esnada meydana gelirse, yeniden çizimi birkaç dakika bekleyebiliriz. Naber?

Dedikleri gibi, ne yazarsan onu alırsın. Göstergelerde yapı 245'ten önce yalnızca bir "giriş noktası" vardı - OnCalculate() işlevi. Elbette ki, göstergenin ilk hesaplamalarını, başlatmasını ve tamamlamasını sağlayan OnInit() ve OnDeinit() işlevlerinden bahsetmiyorum. Şimdi birkaç giriş noktası var ve bunlar yeni Zamanlayıcı ve ChartEvent olaylarıyla bağlantılı.

Ancak, yeni işleyiciler yalnızca dahil oldukları şeyi yapıyorlar ve OnCalculate() işleyicisiyle resmen ilişkili değiller. Peki, "yabancı" OnChartEvent() işleyicimizle "doğru bir şekilde" çalışması için ne yapabiliriz? Yani bu, MA'yı hemen yeniden çizmeye izin verir mi?

Genel olarak, bu gerekliliği uygulamanın birkaç yolu vardır:

  • OnChartEvent() içindeki "Matruşka" (OnCalculate() çağrısı): OnCalculate() işlev çağrısını tüm parametrelerini önceden doldurarak bu işleyiciye ekleyin. OnChartEvent() işleyicisi en az bir MA parametresinin değiştirilmesini gerektirdiği için, o zaman tüm geçmişini etkileyecektir; yani hesaplamaların optimizasyon olmadan onu "sıfırdan" tekrar hesaplamalıyız.
  • Kontrolü, grafik arabelleğini değiştiren OnCalculate() işlevinin başına aktaran "yapay tick". Görünüşe göre, MT5 belgelerinde yansıtıldığı gibi "meşru" yöntemler yoktur (belki de o kadar ayrıntılı aramamış olsam da). İlgileniyorsanız, «API», «PostMessageA» vb. gibi bir şey arayabilirsiniz. Dolayısıyla, bu değişkeni burada dikkate almayacağız; zira bu, belgelenmemiş özelliklerin bir gün değişmeyeceğini garanti etmez. Bunun gerçekleştirilebileceği konusunda herhangi bir şüphem yok.

 

"Matruşka" çalışıyor!

Görünen o ki en önemli şeyi zaten yapmışız. Aşağıda çok basit bir işlev kodu var. Çağrısını doğrudan OnChartEvent() işleyicisinin dönüş işlecinin önüne ekleyebilirsiniz.

int OnCalculate_Void()
{
   const int rates_total = Bars( _Symbol, PERIOD_CURRENT );
   CopyClose( _Symbol, PERIOD_CURRENT, 0, rates_total, _price );
   OnCalculate( rates_total, 0, 0, _price );
   return( 1 );
}//+------------------------------------------------------------------+

Göstergeyi derleyip grafiğe uyguladıktan sonra, kodun genel olarak hızlı bir şekilde ve tick'in ortaya çıkmasından bağımsız çalıştığını görüyoruz.

Bu uygulamanın dezavantajı, Kapanış fiyatlarının tam olarak price[] dizisine kopyalanmasıdır. Arzu edilirse, gösterge özellikleri iletişim kutusunun "Ayarlar" sekmesinde "Uygula" alanını ayarlayarak CopyClose() işlevini istediğimiz şeyle değiştirebiliriz. Mevcut fiyat temel olacaksa (Açılış, Yüksek, Düşük, Kapanış), o zaman karşılık gelen CopyXXXX() işlevine zaten sahibiz demektir. Daha karmaşık fiyatlar durumunda (Ortalama, Tipik veya Ağırlıklı) diziyi farklı şekilde hesaplamamız gerekir.

Dizi geçmişinin tamamını kopyalayan CopyClose() işlevine ihtiyacımız olup olmadığından emin değilim. Diğer yandan, geçmiş çok derinlemesine yüklenmediğinde bu işlev yeterince hızlıdır. Geçmişi 1999'dan önce (yaklaşık 700 bin çubuk) olan EURUSD H1 üzerindeki göstergenin kontrol edilmesi, göstergenin hesaplamalarla ilgilendiğini ve herhangi bir yavaşlama göstermediğini gösterdi. Bu tür bir geçmiş üzerinde olası yavaşlamalar CopyXXXX() işlevinden değil, geçmişin başlangıcından itibaren daha karmaşık gösterge yeniden hesaplama ihtiyacından kaynaklanabilir (bu, zorunludur).


Birkaç bulgu ve sonuç

Daha iyi olan nedir? - Tek gösterge dosyası mı yoksa "gösterge + advisor" ikilisi mi?

Aslında bu soru o kadar da basit değil. Bir yandan, olay işleyicileri de dahil olmak üzere tüm işlevler tek bir yerde toplandığı için, tek bir gösterge dosyamız varsa bu, iyidir.

Diğer yandan, bir Expert Advisor ile birlikte grafiğe uygulanan 3 veya 4 gösterge olduğunu düşünelim - Bu durum nadir değildir. Ayrıca, standart OnCalculate() işlevine ek olarak her göstergenin kendi olay işleyicisi ile donatıldığını varsayın. Bu "rengarenk" olay işlemeyle karışıklığı önlemek için artık göstergelerde izin verilen tüm olay işleyicilerini tek bir yerde - Expert Advisor'da toplamak daha mantıklıdır.

Uzun süredir yazılım geliştiricileri bize göstergedeki olayları işleme yeteneği kazandırmaya karar verdiler: Herkese açık olmayan beta sürümü 09.09.09'dan (gösterge "saf hesaplama ve matematiksel varlık" olarak kabul edildiğinde ve hesaplama hızını engelleyen herhangi bir özellik ile bozulmaması gerektiğinde) bu yana tam olarak 5 ay geçti. Muhtemelen, "fikrin saflığı" zarar görecek - ve şimdi programcı fantezilerine ilişkin gerçek bir kaos ortaya çıkacak. Ancak denge her zaman saf ama sınırlı fikir ile o kadar temiz değil, daha güçlü yetenek arasında ortada bir yerdedir.

Eylül-Ekim 2009'da, MT5 beta sürümünün yapı sayısı 200'e dahi ulaşmadığında, MA parametrelerinin anında yönetilmesine olanak tanıyan "Expert Adviser + Gösterge" ikilisi kodunu yazdım ve hatalarını ayıkladım, ancak "C sınıfında": Bu, yalnızca tick geldikten sonra güncellendi, ancak bu hemen gerçekleşmedi. O sıralarda bu ikili olası tek çözümdü ve şimdi kimsenin ilgisini çekmiyor.

Gösterge işlevselliğini son sürümde sunulduğu gibi, "B sınıfına" nasıl getireceğimi o zaman düşünemedim. Şimdi, bunun ilginç olabileceğini düşünen kişilere daha uygun bir çözüm sunmaktan memnuniyet duyuyorum.


Yaptığımız işi gösteren kısa videom ektedir. MA eğrisinin yumuşak değişimi (yalnızca dönem değişiyor - önce artıyor, sonra azalıyor) bir şekilde göz kamaştırıcı. Bu Matruşka'dır (ünlü Rus oyuncak bebek takımına benzer şekilde).


Elbette, bu tür hileler yalnızca göstergenin sıfırdan hesaplanması çok fazla zaman almadığında yararlıdır. Bu göstergede yer alan basit MA, bu gerekliliği karşılamaktadır.


Bir kaygan görünüm

Göstergenin önceki harici parametrelerinin artık F3 tuşuna basarak görebileceğiniz terminal genel değişkenleri (TGV) olduğunu unutmayın. Genel Değişkenler iletişim kutusunu açtığınızı ve TGV'lerden birini değiştirdiğinizi (örneğin, MA dönemi) varsayalım. Bu değişikliğin hemen grafikteki göstergeye yansımasını beklersiniz.

Şu anda terminalde, kullanıcı tarafından yapılan TGV düzenlemesine karşılık gelen bir olay yok (örneğin, CHARTEVENT_GLOBALVAR_ENDEDIT). Ayrıca, Genel Değişkenler iletişim kutusunda TGV değişikliğini devre dışı bırakamayız. Bu nedenle, burada tick dışında herhangi bir olayı hesaba katamayız. Gerçekte ne olacak?

Klavyeye dokunmazsanız, bir sonraki tıklamada dahi güncelleme "yanlış" olacaktır: Güncellendi değişkeni sıfır olarak ayarlanmamıştır ve bu nedenle yalnızca "optimize edilmiş" gösterge hesaplaması (değiştirilen TGV'nin önceki değerine karşılık gelen) yapılacaktır. Bu durumda, düzeni yeniden sağlamak için tek bir şey tavsiye edebiliriz: TGV'yi düzenledikten sonra, TGV'yi değiştiren, Güncellendi = 0'ı ayarlayan ve göstergenin tam olarak yeniden hesaplanmasına neden olan kısayol tuşuna en az bir kez basmalısınız.

Tüm olası kullanıcılar ve geliştiriciler bu gerçeği göz önünde bulundurmalıdır.


Ekli kaynak kodu ve video dosyaları

Son olarak, kaynak kod dosyalarını ekliyorum. Açıklama:

  1. Özel Hareketli Ortalama.mq5 - MT5 ile birlikte gelen MA kaynak kodu dosyası.
  2. MyMA_ind_with_ChartEvent.mq5 - İlk ("C sınıfı") uygulama: Gösterge yalnızca tick'in ortaya çıkmasından sonra güncellenir.
  3. MyMA_ind_with_ChartEvent_Matryoshka.mq5 - İkinci (belki de, "B sınıfı") varyant: Gösterge, tick'in ortaya çıkmasını beklemeden hemen güncellenir.

MetaQuotes Ltd tarafından Rusçadan çevrilmiştir.
Orijinal makale: https://www.mql5.com/ru/articles/39

Grafik Kontrol Seçenekleri ile Gösterge Oluşturma Grafik Kontrol Seçenekleri ile Gösterge Oluşturma
Piyasa duyarlılığına aşina olanlar MACD göstergesi hakkında bilgi sahibidir (tam adı Hareketli Ortalama Yakınsama/Iraksama'dır) - Bu, yatırımcılar tarafından bilgisayar analiz yöntemlerinin ortaya çıktığı ilk anlardan itibaren kullanılan fiyat hareketini analiz etmek için güçlü bir araçtır. Bu makalede, MACD'ye ilişkin olası değişiklikleri ele alacağız ve bunları, değişiklikler arasında grafiksel olarak geçiş yapma imkanıyla tek bir göstergede uygulayacağız.
MQL5: MetaTrader 5'te Emtia Vadeli İşlemler Ticaret Komisyonu (CFTC) Raporlarının Analizi ve İşlenmesi MQL5: MetaTrader 5'te Emtia Vadeli İşlemler Ticaret Komisyonu (CFTC) Raporlarının Analizi ve İşlenmesi
Bu makalemizde, CFTC rapor analizi için bir araç geliştireceğiz. Şu sorunu çözeceğiz: CFTC rapor verilerinin, Komisyon tarafından sağlanan veri dosyalarından bir ara işleme ve dönüştürme olmadan doğrudan kullanılmasına olanak tanıyan bir gösterge geliştirmek. Ayrıca, bu, farklı amaçlar için kullanılabilir: Verileri bir gösterge olarak çizmek, diğer göstergelerdeki verilerle devam etmek, otomatik analiz için script dosyalarında, alım satım stratejilerinde kullanılmak üzere Expert Advisor'larda.
MetaTrader 5 ve MATLAB Etkileşimi MetaTrader 5 ve MATLAB Etkileşimi
Bu makale MetaTrader 5 ve MatLab matematiksel paketi arasındaki etkileşime ilişkin ayrıntıları içermektedir. Ayrıca MatLab masaüstü ile etkileşimde bulunmak için evrensel bir kitaplık geliştirme süreci olan veri dönüştürme mekanizması gösterilmektedir. Bunun yanı sıra MatLab ortamı tarafından oluşturulan DLL kullanımını da kapsamaktadır. Bu makale, C++ ve MQL5 hakkında bilgi sahibi olan deneyimli okuyuculara yöneliktir.
Yeni Başlayanlar için MQL5'te Dijital Filtrelerin Pratik Uygulaması Yeni Başlayanlar için MQL5'te Dijital Filtrelerin Pratik Uygulaması
Dijital sinyal filtreleme fikri, alım satım sistemlerinin oluşturulmasıyla ilgili forum konularında kapsamlı olarak tartışıldı. Ve MQL5'te standart bir dijital filtre kodu oluşturmamak mantıksız olacaktır. Bu makalede yazar, "Yeni Başlayanlar için MQL5'te Özel Göstergeler" adlı makalesinden basit SMA gösterge kodunun daha karmaşık ve evrensel dijital filtre koduna dönüşümünü açıklamaktadır. Bu makale, mantıksal olarak önceki makalenin devamı niteliğindedir. Ayrıca koddaki metnin nasıl değiştirileceği ve programlama hatalarının nasıl düzeltileceği de anlatılmaktadır.