English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
MQL5 Tarif Defteri: Tipik Grafik Olaylarını İşleme

MQL5 Tarif Defteri: Tipik Grafik Olaylarını İşleme

MetaTrader 5Örnekler | 13 Ocak 2022, 16:37
77 0
Denis Kirichenko
Denis Kirichenko

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

Ş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ın sonucu

Ş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

Ş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

Ş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

Ş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

Ş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ı

Ş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ı

Ş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ı

Ş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ı

Ş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

Ş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ış

Ş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

Ekli dosyalar |
code_en.zip (19.59 KB)
Hesaplamalar için OpenCL Nasıl Yüklenir ve Kullanılır? Hesaplamalar için OpenCL Nasıl Yüklenir ve Kullanılır?
MQL5'in OpenCL için yerel destek sağlamaya başlamasının üzerinden bir yıldan fazla zaman geçti. Ancak, Uzman Danışmanlarında, göstergelerinde veya betiklerinde paralel bilgi işlem kullanmanın gerçek değerini pek de çok kullanıcı görmemiştir. Bu makale, bu teknolojiyi MetaTrader 5 alım satım terminalinde kullanmayı deneyebilmeniz için OpenCL'yi bilgisayarınıza yüklemenize ve kurmanıza yardımcı olma görevi görür.
MQL5 Cloud Network: Hala Hesaplıyor musunuz? MQL5 Cloud Network: Hala Hesaplıyor musunuz?
Yakında MQL5 Cloud Network'ün piyasaya sürülmesinden bu yana bir buçuk yıl geçmiş olacak. Bu öncü olay, yeni bir algoritmik alım satım çağını başlattı - şimdi birkaç tıklamayla, yatırımcıların emrinde alım satım stratejilerinin optimizasyonu için yüzlerce ve binlerce bilgi işlem çekirdeği olabilir.
Bir Diğer MQL5 OOP Sınıfı Bir Diğer MQL5 OOP Sınıfı
Bu makale, bir teorik alım satım fikri tasarlamaktan bu fikri deneysel dünyada gerçek hale getiren bir MQL5 EA programlamaya kadar bir Nesne Yönelimli Uzman Danışmanı sıfırdan nasıl oluşturacağınızı gösterir. Bana göre, yaparak öğrenmek başarılı olmak için sağlam bir yaklaşımdır, bu yüzden fikirlerinizi nihai olarak Forex robotlarınızı kodlamak için nasıl sıraya dizeceğinizi görmeniz için pratik bir örnek göstereceğim. Ayrıca amacım sizi OO ilkelerine bağlı kalmaya davet etmek.
Nokta ve Şekil Grafiği Oluşturma için Gösterge Nokta ve Şekil Grafiği Oluşturma için Gösterge
Mevcut piyasa durumuna dair bilgi sağlayan birçok grafik türü vardır. Nokta ve Şekil grafiği gibi birçoğu uzak geçmişten mirastır. Makale, gerçek zamanlı bir gösterge kullanarak Nokta ve Şekil grafiği oluşturmanın bir örneğini açıklanmaktadır.