MQL5'te olay işleme: MA dönemini anında değiştirme
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:
- Özel Hareketli Ortalama.mq5 - MT5 ile birlikte gelen MA kaynak kodu dosyası.
- MyMA_ind_with_ChartEvent.mq5 - İlk ("C sınıfı") uygulama: Gösterge yalnızca tick'in ortaya çıkmasından sonra güncellenir.
- 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
- Ücretsiz ticaret uygulamaları
- İşlem kopyalama için 8.000'den fazla sinyal
- Finansal piyasaları keşfetmek için ekonomik haberler
Gizlilik ve Veri Koruma Politikasını ve MQL5.com Kullanım Şartlarını kabul edersiniz