MQL5 Tarif Defteri: Tipik Grafik Olaylarını İşleme
Giriş
Makalemde, MQL5 geliştiricileri tarafından önceden tanımlanan tipik (standart) olaylar ile birlikte OnChartEvent() öğesini kullanarak yapılabilecekleri ve uygulamalı pratiği açıklamak isterim MQL5 makalesi ve Code Base halihazırda bu işleyiciyi kullanma örneklerini içermektedir.
Ancak benim amacım, bu enstrümanı Olay Odaklı Programlama (EOP) bağlamında analiz etmek. Bu işleyicinin, tam otomatik ve yarı otomatik alım satım sistemleri için başarıyla kullanılabileceğine inanıyorum.
1. "ChartEvent" Olayı
Öyleyse, ilk olarak bu olay türünün ne olduğunu görelim.
Belgelere göre, ChartEvent olayı, özellikle aşağıdaki durumlarda bir grafik ile çalışırken ortaya çıkabilir:
- bir grafik penceresi odaktayken klavyede bir tuşa basılması.
- bir grafik nesnesi oluşturulması.
- bir grafik nesnesinin silinmesi.
- bir grafik nesnesi üzerine tıklanması.
- bir grafik nesnesinin fare ile sürüklenmesi.
- LabelEdit grafik nesnesinin bir metin alanındaki metin düzenlemesinin tamamlanması.
Dolayısıyla, bu olay etkileşim getirir ve bir çizelge ile etkileşime olanak sağlar. Ayrıca, böyle bir etkileşim, manuel alım satımın yanı sıra bazı algoritmik işlemlerin (otomatik alım satım) bir sonucu olabilir.
MQL5 geliştiricileri, ChartEvent olayını, ENUM_CHART_EVENT numaralandırmasında belirtilen türlere göre sınıflandırır.
Bu listenin, programcıya hizmet etmek için gizli bir rezerv görevi gören bir dizi kullanıcı tanımlı olaya sahip olduğunun belirtilmesi önemlidir. MQL5 geliştiricileri özel olaylar için 65535 kimlik sağlar.
Özel olaylar ile çalışmak için, programcının ihtiyaçlarına yönelik özel bir oluşturucu fonksiyonu -EventChartCustom()- mevcuttur. Ancak, bu makale özel olayları değerlendirmemektedir.
2. ChartEvent İşleyici ve Oluşturucu
ChartEvent olayının işlemesinin tamamı, özel bir işleyici fonksiyonu olan OnChartEvent() ile yapılır. Bu da MQL5 dili konsepti ile tutarlıdır, burada örneğin Trade olayı OnTrade() fonksiyonu ile işlenir, Init olayı OnInit() fonksiyonu ile işlenir ve benzeri.
OnChartEvent() fonksiyonu aşağıdaki imzaya sahiptir:
void OnChartEvent(const int id, // event identifier const long& lparam, // parameter of the event of type long const double& dparam, // parameter of the event of type double const string& sparam // parameter of the event of type string )
Giriş parametrelerinin tamamı sabittir ve işleyici çağrıldığında bunlar bazı faydalı bilgiler iletir.
Böylece, id parametresi değeri, hangi özel olayın işleyiciyi çağırdığını ortaya çıkarabilir. Diğerleri long, double ve string türünde değerlere sahip olabilir. Bu şekilde, bir olay hakkında ek bilgi elde edilebilir.
Daha ileride, belirtilen parametrelerin değerlerinin neler olduğunu analiz etmek için nerede kullanılacağına dair bir örnek oluşturacağız.
Bir programcının uygulaması için hazır bulunan ChartEvent olayının özel parçası EventChartCustom() fonksiyonuna bağlanır. İşte bu fonksiyon olayı oluşturabilir. Fonksiyon imzası aşağıdaki gibidir:
bool EventChartCustom(long chart_id, // receiving chart identifier ushort custom_event_id, // event identifier long lparam, // the long parameter double dparam, // the double parameter string sparam // the string parameter )
Aslında, oluşturucu fonksiyonu bir olay oluşturabilir ve bunu, giriş parametrelerinin herhangi bir değeri ile mevcut olan dahil olmak üzere herhangi bir grafiğe gönderebilir. Sonraki ise türlerdir: ushort, long, double, string.
OnChartEvent() ve EventChartCustom() fonksiyonları birlikte, Olay Odaklı Programlama faydalarının iyi bir örneği olan güçlü bir araç oluşturur.
3. Standart Olay İşleme Şablonu
Şimdi grafik olaylarının türlerini ele alacağım ve bunların her biri için bir örnek vereceğim. Her bir olay, EventProcessor.mq5 dosyasının özel bir sürümüne sahip olacak ve bunun kodu, bir grafik olayının işlenmesini içerecektir. MQL5'te 10 tipik olay vardır.
Bunlardan üçü (fare olayı, grafik nesnesi oluşturma olayı, grafik nesnesi kaldırma olayı) için bir grafik hazırlamalıyız. Bu, ChartSetInteger() fonksiyonu kullanılarak yapılabilir. Bu, bir grafiğin belirtilen olaylara yanıt vermesine olanak sağlar.
Grafik olaylarını işlemek için tipik bir blok şu şekilde görünebilir:
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { string comment="Last event: "; //--- select event on chart switch(id) { //--- 1 case CHARTEVENT_KEYDOWN: { comment+="1) keystroke"; break; } //--- 2 case CHARTEVENT_MOUSE_MOVE: { comment+="2) mouse"; break; } //--- 3 case CHARTEVENT_OBJECT_CREATE: { comment+="3) create graphical object"; break; } //--- 4 case CHARTEVENT_OBJECT_CHANGE: { comment+="4) change object properties via properties dialog"; break; } //--- 5 case CHARTEVENT_OBJECT_DELETE: { comment+="5) delete graphical object"; break; } //--- 6 case CHARTEVENT_CLICK: { comment+="6) mouse click on chart"; break; } //--- 7 case CHARTEVENT_OBJECT_CLICK: { comment+="7) mouse click on graphical object"; break; } //--- 8 case CHARTEVENT_OBJECT_DRAG: { comment+="8) move graphical object with mouse"; break; } //--- 9 case CHARTEVENT_OBJECT_ENDEDIT: { comment+="9) finish editing text"; break; } //--- 10 case CHARTEVENT_CHART_CHANGE: { comment+="10) modify chart"; break; } } //--- Comment(comment); }
Her bir durum için, seçilen bir olayı tanımlayan dizeyi ekledim. Bunun sonucunda, grafikte gerçekleşen son olayı yorum satırında görebiliriz. Şablonu çalıştırırsanız ve grafik üzerinde çeşitli işlemler yaparsanız, yorum satırında farklı kayıtlar olabileceğini fark edeceksiniz.
Açıkçası, sadece olay türünü belirleyen böyle bir Uzman Danışmanın kullanımı çok nadirdir. Bunun yeteneklerini genişletmemiz gerekir.
4. Standart Olay İşleme Örnekleri
4.1. Tuş Vuruşu Olayı
İlk durumu ele alalım ve EA'mızın tuş vuruşlarına yanıt vereceği şekilde klavyedeki düğmeler ile çalışalım. "Yukarı ok" tuşuna basıldığında alış ve "aşağı ok" tuşuna basıldığında satış yapmasına izin verin. O zaman bu durum aşağıdaki şekilde görünecektir:
//--- 1 case CHARTEVENT_KEYDOWN: { //--- "up" arrow if(lparam==38) TryToBuy(); //--- "down" arrow else if(lparam==40) TryToSell(); comment+="1) keystroke"; //--- break; }
TryToBuy() ve TryToSell() uygulamasının ayrıntıları için ekteki EA kaynak koduna bakın. Alım satım parametreleri (lot boyutu, Zarar Durdur, Kâr Al vb.) giriş parametreleri (InpLot, InpStopLoss, InpTakeProfit vb.) olarak belirtilir. Ayrıca, lparam parametresinin basılan tuşun kodunu aldığı da belirtilmelidir.
EA'nın güncellenmiş sürümü EventProcessor1.mq5 olarak adlandırılır.
4.2. Fare Olayı
Bu olay türü yalnızca, grafik için CHART_EVENT_MOUSE_MOVE özelliği belirtilmişse işlenecektir. Bu nedenle EA'nın başlatma bloğu şu dizeleri içerir:
//--- mouse move bool is_mouse=false; if(InpIsEventMouseMove) is_mouse=true; ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,is_mouse);
Bir fare kullanmanız durumunda, doğal olarak, bir fare olayının gerçekleşeceğine dikkat edilmelidir. Bu nedenle, bu olayın işlenmesini devre dışı bırakma imkanı faydalı olabilir. İşleyicinin lparam ve dparam parametreleri sırasıyla X ve Y koordinatlarını rapor etmektedir.
Biz farazi bir örneği tartışacağız. Sağ kenarlıktan sıfır çubuk kayması olduğunu varsayalım. İmlecin ekranın bir kısmı üzerinden kaymanın sağına götürülmesi, alış veya satış öneren bir pencere açacaktır.
Bunun için, önce kaymayı belirlemeliyiz. Sağ kenarlıktan sıfır çubuk kaymasının boyutunu yüzde cinsinden belirlemeye yönelik bir giriş parametresi tanıtacağız (InpChartShiftSize).
Şekil 1. Bir alım satım işleminin penceresi
Kaymayı sağlayan fonksiyonları kullanacağız ve bunun boyutunu belirleyeceğiz: ChartShiftSet() veChartShiftSizeSet(). Daha sonra, imlecin X koordinatının daha önce sınırdan solda olup olmadığını ve sağa hareket edip etmediğini belirleyeceğiz. Hareket etmişse, alış/satış öneren bir pencere görünecektir (Şekil 1).
Ayarlanan hedefi uygulayan kod şu şekilde görünür:
//--- 2 case CHARTEVENT_MOUSE_MOVE: { comment+="2) mouse"; //--- if a mouse event is processed if(InpIsEventMouseMove) { long static last_mouse_x; //--- enable shift if(ChartShiftSet(true)) //--- set shift size if(ChartShiftSizeSet(InpChartShiftSize)) { //--- chart width int chart_width=ChartWidthInPixels(); //--- calculate X coordinate of shift border int chart_shift_x=(int)(chart_width-chart_width*InpChartShiftSize/100.); //--- border crossing condition if(lparam>chart_shift_x && last_mouse_x<chart_shift_x) { int res=MessageBox("Yes: buy / No: sell","Trade operation",MB_YESNO); //--- buy if(res==IDYES) TryToBuy(); //--- sell else if(res==IDNO) TryToSell(); } //--- store mouse X coordinate last_mouse_x=lparam; } } //--- break; }
Alış ve satış, daha önceden oluşturulmuş alım satım fonksiyonları ile yapılır. EA'nın güncellenmiş sürümü EventProcessor2.mq5 olarak adlandırılacaktır.
4.3. Grafik Nesnesi Oluşturma Olayı
Bu olay türü, bir grafikte bir nesne oluşturulduğunda oluşturulur. Fare olayına benzer şekilde, bu türün de CHART_EVENT_OBJECT_CREATE özelliği ile işleme için izin alması gerekir. Başlatma bloğunda, yeni bir grafik nesnesinin ortaya çıkmasına yanıt verip vermeyeceğimizin yalnızca bir kez belirtilmesi gerekir.
//--- object create bool is_obj_create=false; if(InpIsEventObjectCreate) is_obj_create=true; ChartSetInteger(0,CHART_EVENT_OBJECT_CREATE,is_obj_create);
İşleyicinin yalnızca bir parametresi bilgi içerecektir. Oluşturulan grafik nesnesinin adını içeren bir sparam dize parametresidir. Bu nesneyi adı ile bulabilir, bunu ele alabilir ve daha sonra ne yapacağımıza karar verebiliriz.
İşte basit bir örnek. Grafiğe yatay bir çizgi çizeceğiz ve robotun grafiğe yansıtılan tüm çubukların maksimum fiyatına yerleştirmesini ve iki çizgi daha çizmesini sağlayacağız. Alt satır minimum fiyata yerleştirilecek ve üçüncü satır, her ikisinden de eşit mesafede olan ilk ikisi arasında olacaktır.
Görevin uygulanması için kod:
//--- 3 case CHARTEVENT_OBJECT_CREATE: { comment+="3) create graphical object"; //--- if graphical object creation event is processed if(InpIsEventObjectCreate) { //--- capture creation of horizontal line int all_hor_lines=ObjectsTotal(0,0,OBJ_HLINE); //--- if this is the only line if(all_hor_lines==1) { string hor_line_name1=sparam; //--- calculate levels int visible_bars_num=ChartVisibleBars(); //--- arrays for high and low prices double highs[],lows[]; //--- int copied=CopyHigh(_Symbol,_Period,0,visible_bars_num-1,highs); if(copied!=visible_bars_num-1) { Print("Failed to copy highs!"); return; } copied=CopyLow(_Symbol,_Period,0,visible_bars_num-1,lows); if(copied!=visible_bars_num-1) { Print("Failed to copy lows!"); return; } //--- high and low prices double ch_high_pr,ch_low_pr,ch_mid_pr; //--- ch_high_pr=NormalizeDouble(highs[ArrayMaximum(highs)],_Digits); ch_low_pr=NormalizeDouble(lows[ArrayMinimum(lows)],_Digits); ch_mid_pr=NormalizeDouble((ch_high_pr+ch_low_pr)/2.,_Digits); //--- place created line on high if(ObjectFind(0,hor_line_name1)>-1) if(!ObjectMove(0,hor_line_name1,0,0,ch_high_pr)) { Print("Failed to move!"); return; } //--- create line on low string hor_line_name2="Hor_line_min"; //--- if(!ObjectCreate(0,hor_line_name2,OBJ_HLINE,0,0,ch_low_pr)) { Print("Failed to create the 2nd horizontal line!"); return; } //--- create line between high and low string hor_line_name3="Hor_line_mid"; //--- if(!ObjectCreate(0,hor_line_name3,OBJ_HLINE,0,0,ch_mid_pr)) { Print("Failed to create the 3rd horizontal line!"); return; } } } break; }
EA'nın güncellenmiş sürümü EventProcessor3.mq5'tir.
Şekil 2. Bir grafik nesnesi oluşturma işleme olayınınsonucu
Prosedürü tamamladıktan sonra aşağıdaki resmi elde ettim (Şekil 2). Bu şekilde, entegre fonksiyonlar, bir EA'ya bir grafik nesnesinin oluşturulmasına tepki verme ve ardından buna göre hareket etme yeteneği sağlar.
4.4. Bir Özellikler İletişimi yoluyla bir Grafik Nesnesinin Özelliklerini Değiştirme Olayı
Bu olay türü öncekine kısmen benzerdir. Bu, bir grafik nesnesinin özelliklerinden biri, özellikler iletişim kutusu ile değiştirildiğinde tetiklenir. Bu araç, örneğin aynı türde nesnelerin grafik özelliklerinin senkronizasyonu için faydalı olabilir.
Bir grafik üzerinde bazı nesneleri hayal edin. Bir yatırımcının genelde bir grafik üzerinde çok çeşitli çizgileri vardır. Bu çizgilerin, silinmeksizin, bir süre görünmez hale getirilmesi gerekir. Bu görev için bir çözüm bulacağız. Değiştirilmiş çizgi renksiz hale getirilebilir ve diğer grafik nesneleri için de aynısı yapılabilir. Bu durumda kod aşağıdaki şekilde olabilir:
//--- 4 case CHARTEVENT_OBJECT_CHANGE: { comment+="4) change object properties via properties dialog"; //--- string curr_obj_name=sparam; //--- find the changed object if(ObjectFind(0,curr_obj_name)>-1) { //--- get object color color curr_obj_color=(color)ObjectGetInteger(0,curr_obj_name,OBJPROP_COLOR); //--- total number of objects on chart int all_other_objects=ObjectsTotal(0); //--- find other objects for(int obj_idx=0;obj_idx<all_other_objects;obj_idx++) { string other_obj_name=ObjectName(0,obj_idx); if(StringCompare(curr_obj_name,other_obj_name)!=0) if(!ObjectSetInteger(0,other_obj_name,OBJPROP_COLOR,curr_obj_color)) { Print("Failed to change the object color!"); return; } } //--- redraw chart ChartRedraw(); } //--- break;
Grafik üzerinde bir dizi çizgi olduğunu varsayalım (Şekil 3).
Şekil 3. Çok renkli dinamik çizgiler
Çizgilerden herhangi birinin rengini değiştirmeye çalışırsak veya daha özel olarak özellikler iletişim kutusunda bunu renksiz hale getirirsek (Şekil 4), grafikte hiçbir çizgi görünmeyecektir. Aynı zamanda, grafik nesneleri halen orada olacaktır.
Şekil 4. Çizgi rengini değiştirme
EA'nın güncellenmiş sürümü EventProcessor4.mq5 olarak adlandırılır.
4.5. Grafik Nesnesini Silme Olayı
Bu olay türü, adından da anlaşılacağı üzere, bir nesnenin bir grafikten silinmesi üzerine görünür. İşleme için doğrudan bir ön yetkilendirme gerektiren bir grubun son olayıdır. Bu, CHART_EVENT_OBJECT_DELETE özelliği ile yapılabilir.
//--- object delete bool is_obj_delete=false; if(InpIsEventObjectDelete) is_obj_delete=true; ChartSetInteger(0,CHART_EVENT_OBJECT_DELETE,is_obj_delete);
İşte başka bir varsayımsal örnek. EA'nızın bulunduğu grafik üzerinde, farklı türlerde bir dizi grafik nesnesi vardır. Yalnızca belirli bir türdeki nesneleri silmemiz gerektiğini varsayalım. Örneğin dikey çizgiler (Şekil 5).
Şekil 5. Beş dikey çizgi ve diğer çizgiler
Yalnızca bir dikeyi çıkarmamız gerekir, Uzman diğerlerini çıkaracaktır (Şekil 6).
Şekil 6. Kalan çizgiler
"Uzmanlar" kaydında aşağıdaki girişler görünecektir:
NS 0 10:31:17.937 EventProcessor5 (EURUSD.e,W1) Vertical lines before removing: 4 MD 0 10:31:17.937 EventProcessor5 (EURUSD.e,W1) Vertical lines removed from the chart: 4 QJ 0 10:31:18.078 EventProcessor5 (EURUSD.e,W1) Vertical lines after removing: 0
Önemli bir konudan bahsetmek gerekiyor. Bir nesne kaldırıldığında, bunun özelliklerine erişim sağlanamaz. Bunun anlamı, nesneye dair gerekli verileri önceden almazsak, kaldırıldıktan sonra bu bilgilerin erişilebilir olmayacağıdır. Bu nedenle, kaldırılan bir nesnenin türünü bulmamız gerekiyorsa, nesnenin kendisini kaldırılmadan önce bunu saklamamız gerekiyor. MQL5 geliştiricilerine, terminalde bulunan bir grafiğin geçmişini oluşturmalarını öneriyorum. Bu, kaldırılan nesnelerin özelliklerine başvurmamıza olanak sağlayacaktır.
Uzman Danışmanın son sürümünü EventProcessor5.mq5 olarak adlandıracağız.
4.6. Grafik Üzerinde Fare Tıklaması Olayı
Bu olay, grafiğe farenin sol tuşu ile tıklandığında oluşturulacaktır. Grafiğe sağ tıklanması bir içerik menüsü açacaktır ve orta düğmeye tıklanması bir artı işareti getirecektir. İşleyicinin lparam ve dparam parametreleri sırasıyla X ve Y koordinatlarını rapor etmektedir.
Aşağıdaki basit görev örnek teşkil edecektir. Bir "alış" okunun fare tıklamasının gerçekleştiği noktada çizilmesini ayarlamamız gerekiyor. "Ok" nesnesinin yalnızca bir bağlantı noktası vardır. Bunun sonucunda, X ve Y koordinatlarının zaman değerlerine ve bağlantı noktasının fiyatına yalnızca bir dönüşümü gereklidir.
Yukarıdaki örnek için kod:
//--- 6 case CHARTEVENT_CLICK: { comment+="6) mouse click on chart"; //--- object counter static uint sign_obj_cnt; string buy_sign_name="buy_sign_"+IntegerToString(sign_obj_cnt+1); //--- coordinates int mouse_x=(int)lparam; int mouse_y=(int)dparam; //--- time and price datetime obj_time; double obj_price; int sub_window; //--- convert the X and Y coordinates to the time and price values if(ChartXYToTimePrice(0,mouse_x,mouse_y,sub_window,obj_time,obj_price)) { //--- create object if(!ObjectCreate(0,buy_sign_name,OBJ_ARROW_BUY,0,obj_time,obj_price)) { Print("Failed to create buy sign!"); return; } //--- redraw chart ChartRedraw(); //--- increase object counter sign_obj_cnt++; } //--- break; }
Uzmanın mevcut sürümü EventProcessor6.mq5 olarak adlandırılır.
4.7. Bir Grafik Nesnesine Fare Tıklaması Olayı
Grafik olaylarının bu türü, yalnızca bir grafik nesnesi üzerinde bir fare tıklaması olması bakımından öncekinden farklıdır. sparam dize parametresi, tıklanan nesnenin adını içerecektir. Önceki örnekte "alış" okları oluşturmuştuk. Bunu, bu türde nesneye tıklanması bunu bir "satış" okuna dönüştürecek şekilde oluşturalım.
İşleyicinin bu bloğunun kodu şu şekilde görünebilir:
//--- 7 case CHARTEVENT_OBJECT_CLICK: { comment+="7) mouse click on graphical object"; //--- string sign_name=sparam; //--- delete buy arrow if(ObjectDelete(0,sign_name)) { //--- redraw chart ChartRedraw(); //--- static uint sign_obj_cnt; string sell_sign_name="sell_sign_"+IntegerToString(sign_obj_cnt+1); //--- coordinates int mouse_x=(int)lparam; int mouse_y=(int)dparam; //--- time and price datetime obj_time; double obj_price; int sub_window; //--- convert the X and Y coordinates to the time and price values if(ChartXYToTimePrice(0,mouse_x,mouse_y,sub_window,obj_time,obj_price)) { //--- create object if(!ObjectCreate(0,sell_sign_name,OBJ_ARROW_SELL,0,obj_time,obj_price)) { Print("Failed to create sell sign!"); return; } //--- redraw chart ChartRedraw(); //--- increase object counter sign_obj_cnt++; } } //--- break; }
Bu örnek için, bir fare tıklaması işlemesi örneği korudum. EA'yı başlatırken, fareye üç kez sol tıkladım ve üç alış oku elde ettim (Şekil 7). Bunların konumlarını sarı ile vurguladım.
Şekil 7. "Alış" okları
Şimdi her bir "alış" okuna tıklarsak, aşağıdaki resmi elde ederiz (Şekil 8).
Şekil 8. "Alış" ve "Satış" okları
"Satış" okları planlandığı gibi görünmüştür, ancak "alış" okları görünecek şekilde tasarlanmamıştır. Grafikte, "alış" oklarının adlarını sarı renk ile vurguladığım nesnelerin bir listesini getirmemin bir nedeni var.
EA'nın 4., 5. ve 6. "alış" oklarını oluşturduğunu fark etmişsinizdir. Bu neden oldu? Bunun nedeni, nesneye ilk tıklamanın iki olayı tetiklemesidir: ilki, nesneye yapılan asıl tıklama ve ikincisi, grafiğe yapılan tıklamadır. Son olay bir "alış" oku oluşturur. Burada, grafiğe yapılan tıklama olan ikinci olayın işlenmesini önleyecek bir mekanizma ekleme zorunluluğu ortaya çıkıyor. Bana göre, zaman üzerinde kontrol böyle bir mekanizma olabilir.
gLastTime global değişkenini ekleyelim. Bu, bir "alış" oku oluşturma zamanı üzerinde bir kontrolü kolaylaştıracaktır. Basit bir tıklama işleyicisi bir "satış" oku oluşturulmasından itibaren 250 ms'den daha kısa bir sürede çağrılırsa, bu çağrı geçilecektir.
Grafik yeniden çizilmeden önce, aşağıdaki dize, nesne üzerine tıklamayı işleme bloğuna eklenecektir:
//--- store the moment of creation gLastTime=GetTickCount();
Zamanın doğrulanması, grafik üzerine tıklamayı işleme bloğuna eklenmelidir.
uint lastTime=GetTickCount(); if((lastTime-gLastTime)>250) { //--- click handling }
Yeniden "alış" türü grafik üzerinde üç ok oluşturalım (Şekil 9).
Şekil 9. "Alış" okları
Küçük boyutlarına rağmen bunların üzerine tıklamaya çalışacağız. Oklar tıklandığında "satış" türüne dönüşmüştür (Şekil 10).
Şekil 10. "Satış" okları
Daha öncekilere benzer şekilde yeni sürümü EventProcessor7.mq5 olarak adlandıracağız.
4.8. Fare ile Grafik Nesnesini Taşıma Olayı
Bu olay, bir nesne bir grafik alanı içerisinde hareket ettiğinde gerçekleşir. İşleyici, bir sparam dize parametresi hareket ettirilen nesnenin adını alır.
İşte bir başka örnek. Gün içi yatırımcıları genellikle belirli bir zaman aralığında alım satım yaparlar. Dikey çizgiler bir zaman aralığının limitleri olacaktır. Resim yaklaşık olarak Şekil 11'e benzeyecektir. İlgi aralığı vurgulanmıştır.
Şekil 11. Bir zaman aralığının limitleri
Zaman aralığı manuel olarak değiştirilebilir. Bu durumda yarı otomatik sistemimiz böyle bir değişikliğe tepki vermek zorunda kalacaktır.
Global düzeyde, gTimeLimit1_name ve gTimeLimit2_name olmak üzere iki dikey çizginin adlarını tanımlayan değişkenler yaratacağız. Ayrıca, dikdörtgenlerin adları için, grafikteki alım satım yapılmayan zamanları karartan birkaç değişken oluşturmamız gerekiyor. Bağlantı noktaları için global değişkenlerin de oluşturulması gerekecektir. İki dikdörtgenimiz olduğu için dört noktamız olacaktır.
CHARTEVENT_OBJECT_DRAG işleyicisi durumunun kodu:
//--- 8 case CHARTEVENT_OBJECT_DRAG: { comment+="8) move graphical object with mouse"; string curr_obj_name=sparam; //--- if one of the vertical lines is moved if(!StringCompare(curr_obj_name,gTimeLimit1_name) || !StringCompare(curr_obj_name,gTimeLimit2_name)) { //--- the time coordinate of vertical lines datetime time_limit1=0; datetime time_limit2=0; //--- find the first vertical line if(ObjectFind(0,gTimeLimit1_name)>-1) time_limit1=(datetime)ObjectGetInteger(0,gTimeLimit1_name,OBJPROP_TIME); //--- find the second vertical line if(ObjectFind(0,gTimeLimit2_name)>-1) time_limit2=(datetime)ObjectGetInteger(0,gTimeLimit2_name,OBJPROP_TIME); //--- if vertical lines are found if(time_limit1>0 && time_limit2>0) if(time_limit1<time_limit2) { //--- update properties of rectangles datetime start_time=time_limit1; datetime finish_time=time_limit2; //--- if(RefreshRecPoints(start_time,finish_time)) { //--- if(!ObjectMove(0,gRectLimit1_name,0,gRec1_time1,gRec1_pr1)) { Print("Failed to move the 1st point!"); return; } if(!ObjectMove(0,gRectLimit1_name,1,gRec1_time2,gRec1_pr2)) { Print("Failed to move the 2nd point!"); return; } //--- if(!ObjectMove(0,gRectLimit2_name,0,gRec2_time1,gRec2_pr1)) { Print("Failed to move the 1st point!"); return; } if(!ObjectMove(0,gRectLimit2_name,1,gRec2_time2,gRec2_pr2)) { Print("Failed to move the 2nd point!"); return; } } } } //--- break; }
Bu kod RefreshRecPoints() özel fonksiyonunu içerir. Bu, iki dikdörtgen için bağlantı noktalarının değerlerinin güncellenmesiyle ilgilenir. EA başlatma bloğu, grafik nesneleri oluşturulmasına dair bilgi sağlayabilir. Güncellenmiş sürümü EventProcessor8.mq5 olarak adlandırılacaktır.
4.9. Metin Alanında Bir Metin Düzenlemesinin Sonu Olayı
Bu olay türü, oldukça özel bir yapıdadır ve veri girişi alanındaki metin düzenlenirken görünür. sparam parametresi, üzerinde çalışılan nesnenin adını içerir.
İşte değerlendirilecek bir örnek. Veri girişi alanına, yürüteceğimiz alım satım işlemini gireceğiz. Burada sadece iki işlem olsun: alış ve satış. Giriş alanına "Alış" kelimesini girersek, EA bir varlık satın alacak ve "Satış" kelimesini girersek bu varlık satılacaktır. Bu alanı büyük/küçük harfe duyarsız şekilde ayarlayacağız, yani "alış" ve "satış" yazabiliriz. Metin ve giriş alanı, satışta kırmızı renkte ve alışta mavi renkte olacaktır (Şekil 12).
Şekil 12. Metin alanı aracılığıyla alış
CHARTEVENT_OBJECT_ENDEDIT durumundaki kod:
//--- 9 case CHARTEVENT_OBJECT_ENDEDIT: { comment+="9) end of editing a text in the data entry field"; //--- string curr_obj_name=sparam; //--- if specified text field is being edited if(!StringCompare(curr_obj_name,gEdit_name)) { //--- get object description string obj_text=NULL; if(ObjectGetString(0,curr_obj_name,OBJPROP_TEXT,0,obj_text)) { //--- check value if(!StringCompare(obj_text,"Buy",false)) { if(TryToBuy()) //--- set text color ObjectSetInteger(0,gEdit_name,OBJPROP_COLOR,clrBlue); } else if(!StringCompare(obj_text,"Sell",false)) { if(TryToSell()) //--- set text color ObjectSetInteger(0,gEdit_name,OBJPROP_COLOR,clrRed); } else { //--- set text color ObjectSetInteger(0,gEdit_name,OBJPROP_COLOR,clrGray); } //--- redraw chart ChartRedraw(); } } //--- break; }
EA'nın güncellenmiş sürümü EventProcessor9.mq5 olarak adlandırılır. Metin alanı oluşturma bloğunu kaynak dosyasında bulabilirsiniz.
4.10. Grafik Değişikliği Olayı
Bu makalede değerlendireceğimiz son olay, grafiğin ayarlarının değiştirilmesi ile ilgilidir. Bu olay, bu noktada grafikteki nesneler ile değil, grafiğin kendisi ile ilgilendiğimizden dolayı özeldir. Geliştiriciler, bu olayın, bir grafiğin boyutu değiştirildiğinde veya yeni bir ayar girildiğinde oluştuğunu söylüyor.
İşte bir başka örnek. Grafik ayarlarından bazılarının değiştirilmesinin yasak olduğunu varsayalım. Bu durumda, kısıtlama kapsamındaki ayarları değiştirme girişimleri yok sayılacaktır. Aslında, EA yalnızca önceki değerleri döndürecektir. Grafiğin aşağıdaki parametrelerini düzeltelim:
- görüntüleme ızgarası;
- grafik görüntüleme türü;
- arka plan rengi.
Bu durum için kod:
//--- 10 case CHARTEVENT_CHART_CHANGE: { //--- current height and width of the chart int curr_ch_height=ChartHeightInPixelsGet(); int curr_ch_width=ChartWidthInPixels(); //--- if chart height and width have not changed if(gChartHeight==curr_ch_height && gChartWidth==curr_ch_width) { //--- fix the properties: //--- display grid if(!ChartShowGridSet(InpToShowGrid)) { Print("Failed to show grid!"); return; } //--- type of chart display if(!ChartModeSet(InpMode)) { Print("Failed to set mode!"); return; } //--- background color if(!ChartBackColorSet(InpBackColor)) { Print("Failed to set background сolor!"); return; } } //--- store window dimensions else { gChartHeight=curr_ch_height; gChartWidth=curr_ch_width; } //--- comment+="10) modify chart"; //--- break; }
Son sürüm EventProcessor10.mq5 olarak adlandırılacaktır.
Sonuç
Bu makalede MetaTrader 5'teki tipik grafik olaylarının çeşitlerini göstermeye çalıştım. Bu olay işleme örneklerinin MQL5'te kodlamaya başlayan programcılar için faydalı olacağını umuyorum.
MetaQuotes Ltd tarafından Rusçadan çevrilmiştir.
Orijinal makale: https://www.mql5.com/ru/articles/689
- Ü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