English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
MQL5 Tarif Defteri Birkaç Zaman Aralığını Tek bir Pencerede Görüntüleme

MQL5 Tarif Defteri Birkaç Zaman Aralığını Tek bir Pencerede Görüntüleme

MetaTrader 5Örnekler | 13 Ocak 2022, 16:50
108 0
Anatoli Kazharski
Anatoli Kazharski

Giriş

Bir pozisyon açmak için yönü seçerken, aynı anda görüntülenen birçok zaman aralığı olan bir fiyat grafiği oldukça faydalı olabilir. MetaTrader 5 İstemci Terminali analiz için 21 zaman aralığı sağlar. Mevcut grafiğe yerleştirebileceğiniz özel grafik nesnelerinden yararlanabilir ve sembolü, zaman aralığını ve diğer bazı özellikleri tam buradan ayarlayabilirsiniz. Bu grafik nesnelerinden herhangi bir sayıda ekleyebilirsiniz, ancak bu, manuel olarak yapıldığından oldukça kullanışsız ve zaman alıcı olacaktır. Hepsinden de öte, tüm grafik özellikleri manuel modda ayarlanamamaktadır.

Bu makalede, bu grafik nesnelerine daha yakından bakacağız. Örnekleme amacıyla, bir alt pencerede aynı anda birçok grafik nesnesi ayarlamamıza olanak sağlayacak kontrollere (düğmelere) sahip bir gösterge oluşturacağız. Ayrıca, grafik nesneleri alt pencereye tam olarak sığar ve ana grafik veya terminal penceresi yeniden boyutlandırıldığında otomatik olarak ayarlanır.

Grafik nesneleri eklemek için düğmelere ek olarak, programlı olarak değiştirilebilenler dahil olmak üzere grafik özelliklerinden bazılarının etkinleştirilmesi/devre dışı bırakılmasına yönelik düğmelerimiz de vardır.


Geliştirme

Ekle menüsü->Nesneler->Grafik Nesneleri->Grafik yolunu kullanarak bir grafik nesnesini manuel olarak ekleyebilirsiniz. Örneğin H4 ve D1 zaman aralıklarına sahip nesneler 1 Saatlik grafikte şu şekilde gösterilir:

Şekil 1. Grafik nesneleri

Şekil 1. Grafik nesneleri

Nesne parametrelerini değiştirerek yalnızca sınırlı bir özellikler setini yönetebilirsiniz:

Şekil 2. Grafik nesnesi özellikleri

Şekil 2. Grafik nesnesi özellikleri

Ancak, satış (ask) ve alış (bid) fiyat seviyeleri, sağ grafik kenarından girintili şekilde, alım satım seviyeleri vb. gibi parametreler yalnızca uygun bir şekilde programlandığında görüntülenebilir.

Hadi gösterge geliştirmeye başlayalım. Diyelim ki, bunun adını ChartObjects (makalenin çalışma başlığı) koyduk. MQL5 Sihirbazını kullanarak MetaEditor'da gösterge için bir şablon oluşturun. Özel Gösterge programının olay işleyicileri için seçim yaparken, aşağıdaki ekran görüntüsünde gösterilenleri seçin:

Şekil 3. Göstergenin olay işleyicileri

Şekil 3. Göstergenin olay işleyicileri

MetaEditor'da açıldığında şablon kaynağı nihai olarak şu şekilde görünecektir:

//+------------------------------------------------------------------+
//|                                                 ChartObjects.mq5 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_chart_window
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| TradeTransaction function                                        |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---
   
  }
//+------------------------------------------------------------------+

Bu uygulamada temel olarak OnCalculate() fonksiyonuna ihtiyaç duymayacağız, ancak göstergeyi bu olmaksızın derlemek imkansızdır. Ayrıca, ana fonksiyonlardan birine ihtiyacımız olacak: OnDeinit(). Bu, programın grafikten silinmesini görüntüleyecektir. Şablonun ana işlemesinin ardından aşağıdaki kaynak kodumuz olacak:

//+------------------------------------------------------------------+
//|                                                 ChartObjects.mq5 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//---
#property indicator_chart_window // Indicator is in the main window
#property indicator_plots 0      // Zero plotting series
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Set the short name for the indicator
   IndicatorSetString(INDICATOR_SHORTNAME,"TimeFramesPanel");
//--- Initialization completed successfully
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Indicator deinitialization                                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- If the indicator has been deleted from the chart
   if(reason==REASON_REMOVE)
     {
     }
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//---

//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//---

  }
//+------------------------------------------------------------------+

Şimdi, grafik nesneleri için depo (alt pencere) olarak kullanılacak bir gösterge oluşturmamız gerekiyor. Bu temel olarak bir sahte gösterge olacak. Buna SubWindow diyelim. Kodu aşağıda verilmektedir:

//+------------------------------------------------------------------+
//|                                                    SubWindow.mq5 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//---
#property indicator_chart_window // Indicator is in the subwindow
#property indicator_plots 0      // Zero plotting series
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Set the short name for the indicator
   IndicatorSetString(INDICATOR_SHORTNAME,"SubWindow");
//--- Initialization completed successfully
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
//---
   
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+

SubWindow.ex5 göstergesi, derleme sonrası ChartObjects.ex5 altında bir kaynak olarak saklanacaktır. Dolayısıyla, program geliştirici son kullanıcıya nihai olarak iki yerine yalnızca bir dosya sağlayabilecektir.

"MQL5 Tarif Defteri: MetaTrader 5 Alım Satım Olayları için Sesli Bildirimler" başlıklı önceki makalede halihazırda açıklandığı gibi kaynak dosyaları, #resource direktifini kullanarak programa dahil edilebilir. ChartObjects programımızın başında, aşağıdaki kod dizesini eklememiz gerekiyor:

//--- Include indicator resource
#resource "\\Indicators\\SubWindow.ex5"

Daha sonra, #define direktifini kullanarak, kontrollere atanacak dizilerin boyutlarını ayarlıyoruz:

//--- Number of time frame buttons
#define TIMEFRAME_BUTTONS 21
//--- Number of buttons for chart object properties
#define PROPERTY_BUTTONS 5

Ve her zamanki gibi, programın en başında global değişkenleri bildiriyoruz:

//--- Location of the SubWindow indicator in the resource
string subwindow_path         ="::Indicators\\SubWindow.ex5";
int    subwindow_number       =-1;               // Subwindow number
int    subwindow_handle       =INVALID_HANDLE;   // SubWindow indicator handle
string subwindow_shortname    ="SubWindow";      // Short name of the indicator
//---
int    chart_width            =0;                // Chart width
int    chart_height           =0;                // Chart height
int    chart_scale            =0;                // Chart scale
//---
color  cOffButtonFont         =clrWhite;         // Unclicked button text color
color  cOffButtonBackground   =clrDarkSlateGray; // Unclicked button background color
color  cOffButtonBorder       =clrLightGray;     // Unclicked button border color
//---
color  cOnButtonFont          =clrGold;          // Clicked button text color
color  cOnButtonBackground    =C'28,47,47';      // Clicked button background color
color  cOnButtonBorder        =clrLightGray;     // Clicked button border color

Bunu zaman aralığı düğmeleri için dizilerin bildirilmesi izler:

//--- Array of object names for time frame buttons
string timeframe_button_names[TIMEFRAME_BUTTONS]=
  {
   "button_M1","button_M2","button_M3","button_M4","button_M5","button_M6","button_M10",
   "button_M12","button_M15","button_M20","button_M30","button_H1","button_H2","button_H3",
   "button_H4","button_H6","button_H8","button_H12","button_D1","button_W1","button_MN"
  };
//--- Array of text displayed on time frame buttons
string timeframe_button_texts[TIMEFRAME_BUTTONS]=
  {
   "M1","M2","M3","M4","M5","M6","M10",
   "M12","M15","M20","M30","H1","H2","H3",
   "H4","H6","H8","H12","D1","W1","MN"
  };
//--- Array of time frame button states
bool timeframe_button_states[TIMEFRAME_BUTTONS]={false};

Grafik nesnesi özelliklerini kontrol etmek için düğme dizileri:

//--- Array of object names for buttons of chart properties
string property_button_names[PROPERTY_BUTTONS]=
  {
   "property_button_date","property_button_price",
   "property_button_ohlc","property_button_askbid",
   "property_button_trade_levels"
  };
//--- Array of text displayed on buttons of chart properties
string property_button_texts[PROPERTY_BUTTONS]=
  {
   "Date","Price","OHLC","Ask / Bid","Trade Levels"
  };
//--- Array of states for buttons of chart properties
bool property_button_states[PROPERTY_BUTTONS]={false};

//--- Array of sizes for buttons of chart properties
int property_button_widths[PROPERTY_BUTTONS]=
  {
   66,68,66,100,101
  };

Ve son olarak grafik nesnesi adlarının bir dizisini elde ediyoruz:

//--- Array of chart object names
string chart_object_names[TIMEFRAME_BUTTONS]=
  {
   "chart_object_m1","chart_object_m2","chart_object_m3","chart_object_m4","chart_object_m5","chart_object_m6","chart_object_m10",
   "chart_object_m12","chart_object_m15","chart_object_m20","chart_object_m30","chart_object_h1","chart_object_h2","chart_object_h3",
   "chart_object_h4","chart_object_h6","chart_object_h8","chart_object_h12","chart_object_d1","chart_object_w1","chart_object_mn"
  };

Grafik nesnelerinin etkileşimi ile ilgili olan fonksiyonlara geçmeden önce, ilk olarak grafikte bu nesneleri oluşturan fonksiyonları yazalım. Programımızda, grafik nesnelerinin iki türüne ihtiyacımız olacak: OBJ_BUTTON ve OBJ_CHART.

Düğmeler CreateButton() fonksiyonu ile oluşturulacaktır:

//+------------------------------------------------------------------+
//| Creating the Button object                                       |
//+------------------------------------------------------------------+
void CreateButton(long              chart_id,         // chart id
                  int               window_number,    // window number
                  string            name,             // object name
                  string            text,             // displayed name
                  ENUM_ANCHOR_POINT anchor,           // anchor point
                  ENUM_BASE_CORNER  corner,           // chart corner
                  string            font_name,        // font
                  int               font_size,        // font size
                  color             font_color,       // font color
                  color             background_color, // background color
                  color             border_color,     // border color
                  int               x_size,           // width
                  int               y_size,           // height
                  int               x_distance,       // X-coordinate
                  int               y_distance,       // Y-coordinate
                  long              z_order)          // Z-order
  {
//--- If the object has been created successfully
   if(ObjectCreate(chart_id,name,OBJ_BUTTON,window_number,0,0))
     {
      // set its properties
      ObjectSetString(chart_id,name,OBJPROP_TEXT,text);                  // setting name
      ObjectSetString(chart_id,name,OBJPROP_FONT,font_name);             // setting font
      ObjectSetInteger(chart_id,name,OBJPROP_COLOR,font_color);          // setting font color
      ObjectSetInteger(chart_id,name,OBJPROP_BGCOLOR,background_color);  // setting background color
      ObjectSetInteger(chart_id,name,OBJPROP_BORDER_COLOR,border_color); // setting border color
      ObjectSetInteger(chart_id,name,OBJPROP_ANCHOR,anchor);             // setting anchor point
      ObjectSetInteger(chart_id,name,OBJPROP_CORNER,corner);             // setting chart corner
      ObjectSetInteger(chart_id,name,OBJPROP_FONTSIZE,font_size);        // setting font size
      ObjectSetInteger(chart_id,name,OBJPROP_XSIZE,x_size);              // setting width
      ObjectSetInteger(chart_id,name,OBJPROP_YSIZE,y_size);              // setting height
      ObjectSetInteger(chart_id,name,OBJPROP_XDISTANCE,x_distance);      // setting X-coordinate
      ObjectSetInteger(chart_id,name,OBJPROP_YDISTANCE,y_distance);      // setting Y-coordinate
      ObjectSetInteger(chart_id,name,OBJPROP_SELECTABLE,false);          // object is not available for selection
      ObjectSetInteger(chart_id,name,OBJPROP_STATE,false);               // button state (clicked/unclicked)
      ObjectSetInteger(chart_id,name,OBJPROP_ZORDER,z_order);            // Z-order for getting the click event
      ObjectSetString(chart_id,name,OBJPROP_TOOLTIP,"\n");               // no tooltip
     }
  }

Buna uygun olarak, bir grafiğin bir alt pencerede oluşturulması CreateChartInSubwindow() fonksiyonu ile gerçekleştirilecektir:

//+------------------------------------------------------------------+
//| Creating a chart object in a subwindow                           |
//+------------------------------------------------------------------+
void CreateChartInSubwindow(int             window_number,  // subwindow number
                            int             x_distance,     // X-coordinate
                            int             y_distance,     // Y-coordinate
                            int             x_size,         // width
                            int             y_size,         // height
                            string          name,           // object name
                            string          symbol,         // symbol
                            ENUM_TIMEFRAMES timeframe,      // time frame
                            int             subchart_scale, // bar scale
                            bool            show_dates,     // show date scale
                            bool            show_prices,    // show price scale
                            bool            show_ohlc,      // show OHLC prices
                            bool            show_ask_bid,   // show ask/bid levels
                            bool            show_levels,    // show trade levels
                            string          tooltip)        // tooltip
  {
//--- If the object has been created successfully
   if(ObjectCreate(0,name,OBJ_CHART,window_number,0,0))
     {
      //--- Set the properties of the chart object
      ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_LEFT_UPPER);   // chart corner
      ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x_distance);       // X-coordinate
      ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y_distance);       // Y-coordinate
      ObjectSetInteger(0,name,OBJPROP_XSIZE,x_size);               // width
      ObjectSetInteger(0,name,OBJPROP_YSIZE,y_size);               // height
      ObjectSetInteger(0,name,OBJPROP_CHART_SCALE,subchart_scale); // bar scale
      ObjectSetInteger(0,name,OBJPROP_DATE_SCALE,show_dates);      // date scale
      ObjectSetInteger(0,name,OBJPROP_PRICE_SCALE,show_prices);    // price scale
      ObjectSetString(0,name,OBJPROP_SYMBOL,symbol);               // symbol
      ObjectSetInteger(0,name,OBJPROP_PERIOD,timeframe);           // time frame
      ObjectSetString(0,name,OBJPROP_TOOLTIP,tooltip);             // tooltip
      ObjectSetInteger(0,name,OBJPROP_BACK,false);                 // object in the foreground
      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);           // object is not available for selection
      ObjectSetInteger(0,name,OBJPROP_COLOR,clrWhite);             // white color
      //--- Get the chart object identifier
      long subchart_id=ObjectGetInteger(0,name,OBJPROP_CHART_ID);
      //--- Set the special properties of the chart object
      ChartSetInteger(subchart_id,CHART_SHOW_OHLC,show_ohlc);           // OHLC
      ChartSetInteger(subchart_id,CHART_SHOW_TRADE_LEVELS,show_levels); // trade levels
      ChartSetInteger(subchart_id,CHART_SHOW_BID_LINE,show_ask_bid);    // bid level
      ChartSetInteger(subchart_id,CHART_SHOW_ASK_LINE,show_ask_bid);    // ask level
      ChartSetInteger(subchart_id,CHART_COLOR_LAST,clrLimeGreen);       // color of the level of the last executed deal 
      ChartSetInteger(subchart_id,CHART_COLOR_STOP_LEVEL,clrRed);       // color of Stop order levels  
      //--- Refresh the chart object
      ChartRedraw(subchart_id);
     }
  }

Yukarıdaki kodda, ilk olarak bir grafik nesnesi için standart grafik özelliklerini ayarlıyoruz. Grafik nesnesi tanımlayıcıyı elde ettikten sonra özel özellikler ayarlanır. Aynı zamanda grafik nesnesini ChartRedraw() fonksiyonunu kullanarak yenilemek önemlidir, burada grafik nesne tanımlayıcı buna aktarılır.

Kontrollerin ayarlarını iki fonksiyona bölelim: AddTimeframeButtons() ve AddPropertyButtons():

//+------------------------------------------------------------------+
//| Adding time frame buttons                                        |
//+------------------------------------------------------------------+
void AddTimeframeButtons()
  {
   int x_dist =1;   // Indent from the left side of the chart
   int y_dist =125; // Indent from the bottom of the chart
   int x_size =28;  // Button width
   int y_size =20;  // Button height
//---
   for(int i=0; i<TIMEFRAME_BUTTONS; i++)
     {
      //--- If 7 buttons have already been added to the same row, set the coordinates for the next row
      if(i%7==0)
        {
         x_dist=1;
         y_dist-=21;
        }
      //--- Add a time frame button
      CreateButton(0,0,timeframe_button_names[i],timeframe_button_texts[i],
                   ANCHOR_LEFT_LOWER,CORNER_LEFT_LOWER,"Arial",8,
                   cOffButtonFont,cOffButtonBackground,cOffButtonBorder,
                   x_size,y_size,x_dist,y_dist,3);
      //--- Set the X-coordinate for the next button
      x_dist+=x_size+1;
     }
  }
//+------------------------------------------------------------------+
//| Adding buttons of chart properties                               |
//+------------------------------------------------------------------+
void AddPropertyButtons()
  {
   int x_dist =1;  // Indent from the left side of the chart
   int y_dist =41; // Indent from the bottom of the chart
   int x_size =66; // Button width
   int y_size =20; // Button height
//---
   for(int i=0; i<PROPERTY_BUTTONS; i++)
     {
      //--- If the first three buttons have already been added, set the coordinates for the next row
      if(i==3)
        {
         x_dist=1;
         y_dist-=21;
        }
      //--- Add a button
      CreateButton(0,0,property_button_names[i],property_button_texts[i],
                   ANCHOR_LEFT_LOWER,CORNER_LEFT_LOWER,"Arial",8,
                   cOffButtonFont,cOffButtonBackground,cOffButtonBorder,
                   property_button_widths[i],y_size,x_dist,y_dist,3);
      //--- Set the X-coordinate for the next button
      x_dist+=property_button_widths[i]+1;
     }
  } 

Göstergeyi grafikten silerken, aynı zamanda program tarafından oluşturulan nesneleri de silmeliyiz. Bunun için, sadece aşağıdaki yardımcı fonksiyonlara ihtiyacımız var:

//+------------------------------------------------------------------+
//| Deleting the panel with time frame buttons                       |
//+------------------------------------------------------------------+
void DeleteTimeframeButtons()
  {
   for(int i=0; i<TIMEFRAME_BUTTONS; i++)
      DeleteObjectByName(timeframe_button_names[i]);
  }
//+------------------------------------------------------------------+
//| Deleting the panel with buttons of chart properties              |
//+------------------------------------------------------------------+
void DeletePropertyButtons()
  {
   for(int i=0; i<PROPERTY_BUTTONS; i++)
      DeleteObjectByName(property_button_names[i]);
  }
//+------------------------------------------------------------------+
//| Deleting objects by name                                         |
//+------------------------------------------------------------------+
void DeleteObjectByName(string object_name)
  {
//--- If such object exists
   if(ObjectFind(ChartID(),object_name)>=0)
     {
      //--- Delete it or print the relevant error message
      if(!ObjectDelete(ChartID(),object_name))
         Print("Error ("+IntegerToString(GetLastError())+") when deleting the object!");
     }
  } 

Şimdi, gösterge yüklenirken panelin grafik üzerinde ayarlandığından ve gösterge grafikten silinirken tüm panel nesnelerinin silindiğinden emin olmak için, OnInit() ve OnDeinit() işleyici fonksiyonlarına aşağıdaki kod dizelerini eklememiz gerekiyor:

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Add the panel with time frame buttons to the chart
   AddTimeframeButtons();
//--- Add the panel with buttons of chart properties to the chart
   AddPropertyButtons();
//--- Redraw the chart
   ChartRedraw();
//--- Initialization completed successfully
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Indicator deinitialization                                       |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- If the indicator has been deleted from the chart
   if(reason==REASON_REMOVE)
     {
      //--- Delete buttons
      DeleteTimeframeButtons();
      DeletePropertyButtons();
      //--- Redraw the chart
      ChartRedraw();
     }
  }

Şimdi göstergeyi derlediysek ve bunu grafiğe eklediysek, paneli aşağıdaki ekran görüntüsünde gösterildiği şekilde görürüz:

Şekil 4. Düğmelerin olduğu panel

Şekil 4. Düğmelerin olduğu panel

Artık kullanıcı ve panel arasındaki etkileşme yönelik fonksiyonları oluşturmaya başlamak için her şey hazır. Bunların büyük ölçüde tamamı, ana OnChartEvent() fonksiyonundan çağrılacaktır. Bu makalede, bu fonksiyonda işlenecek iki olayı ele alacağız:

  • CHARTEVENT_OBJECT_CLICK - bir grafik nesnesi üzerine tıklama olayı.
  • CHARTEVENT_CHART_CHANGE - grafiğin yeniden boyutlandırılması ve grafik özelliklerinin özellikler iletişim penceresi kullanılarak değiştirilmesi olayı.

CHARTEVENT_OBJECT_CLICK olayı ile başlayalım. Yazmak üzere olduğumuz ChartEventObjectClick() fonksiyonu, OnChartEvent() fonksiyonundan tüm argümanları alacaktır (diğer olaylar için benzer fonksiyonlar oluşturacağız):

//+------------------------------------------------------------------+
//| Event of the click on a graphical object                         |
//+------------------------------------------------------------------+
bool ChartEventObjectClick(int id,
                           long lparam,
                           double dparam,
                           string sparam)
  {
//--- Click on a graphical object
   if(id==CHARTEVENT_OBJECT_CLICK)
     {
      //--- If a time frame button has been clicked, set/delete 'SubWindow' and a chart object
      if(ToggleSubwindowAndChartObject(sparam))
         return(true);
      //--- If a button of chart properties has been clicked, set/delete the property in chart objects
      if(ToggleChartObjectProperty(sparam))
         return(true);
     }
//---
   return(false);
  }

ChartEventObjectClick() fonksiyon kodu basittir. Panel düğmesine tıklama olayı tanımlayıcı kullanılarak belirlenir. Ardından, uygulama mantığı iki yöne bölünür: zaman aralığı düğmelerine tıklama olayını veya grafik özellikleri düğmelerine tıklama olayını ele alma. Sol tıklanan nesnenin adını içeren sparam dize parametresi ilgili ToggleSubwindowAndChartObject() ve ToggleChartObjectProperty() fonksiyonlarına aktarılır.

Bu fonksiyonların kaynak koduna bir göz atalım. ToggleSubwindowAndChartObject() ile başlayacağız:

//+------------------------------------------------------------------+
//| Setting/deleting SubWindow and a chart object                    |
//+------------------------------------------------------------------+
bool ToggleSubwindowAndChartObject(string clicked_object_name)
  {
//--- Make sure that the click was on the time frame button object
   if(CheckClickOnTimeframeButton(clicked_object_name))
     {
      //--- Check if the SubWindow exists
      subwindow_number=ChartWindowFind(0,subwindow_shortname);
      //--- If the SubWindow does not exist, set it
      if(subwindow_number<0)
        {
         //--- If the SubWindow is set
         if(AddSubwindow())
           {
            //--- Add chart objects to it
            AddChartObjectsToSubwindow(clicked_object_name);
            return(true);
           }
        }
      //--- If the SubWindow exists
      if(subwindow_number>0)
        {
         //--- Add chart objects to it
         AddChartObjectsToSubwindow(clicked_object_name);
         return(true);
        }
     }
//---
   return(false);
  }

Yukarıdaki kodda verilen yorumları kullanarak uygulama mantığını kolayca anlayabilmeniz gerekir. Vurgulanan dizeler, kodu aşağıda bulunabilen bazı özel fonksiyonları içerir.

CheckClickOnTimeframeButton() fonksiyonu, tıklanan düğme zaman aralıkları paneli ile ilişkili ise true döndürür.

//+------------------------------------------------------------------+
//| Checking if a time frame button has been clicked                 |
//+------------------------------------------------------------------+
bool CheckClickOnTimeframeButton(string clicked_object_name)
  {
//--- Iterate over all time frame buttons and check the names 
   for(int i=0; i<TIMEFRAME_BUTTONS; i++)
     {
      //--- Report the match
      if(clicked_object_name==timeframe_button_names[i])
         return(true);
     }
//---
   return(false);
  }

Bir zaman aralığı düğmesine tıklama onaylandıysa, SubWindow'un şu anda ana grafiğe eklenip eklenmediğini kontrol ederiz. Onaylanmadıysa bu, AddSubwindow() fonksiyonu kullanılarak ayarlanır:

//+------------------------------------------------------------------+
//| Adding a subwindow for chart objects                             |
//+------------------------------------------------------------------+
bool AddSubwindow()
  {
//--- Get the "SubWindow" indicator handle
   subwindow_handle=iCustom(_Symbol,_Period,subwindow_path);
//--- If the handle has been obtained
   if(subwindow_handle!=INVALID_HANDLE)
     {
      //--- Determine the number of windows in the chart for the subwindow number
      subwindow_number=(int)ChartGetInteger(0,CHART_WINDOWS_TOTAL);
      //--- Add the SubWindow to the chart
      if(!ChartIndicatorAdd(0,subwindow_number,subwindow_handle))
         Print("Failed to add the SUBWINDOW indicator ! ");
      //--- The subwindow exists
      else
         return(true);
     }
//--- There is no subwindow
   return(false);
  }

Ardından AddChartObjectsToSubwindow() fonksiyonunu kullanarak oluşturulan alt pencereye grafik nesnelerini ekleriz:

//+------------------------------------------------------------------+
//| Adding chart objects to the subwindow                            |
//+------------------------------------------------------------------+
void AddChartObjectsToSubwindow(string clicked_object_name)
  {
   ENUM_TIMEFRAMES tf                 =WRONG_VALUE; // Time frame
   string          object_name        ="";          // Object name
   string          object_text        ="";          // Object text
   int             x_distance         =0;           // X-coordinate
   int             total_charts       =0;           // Total chart objects
   int             chart_object_width =0;           // Chart object width
//--- Get the bar scale and SubWindow height/width
   chart_scale=(int)ChartGetInteger(0,CHART_SCALE);
   chart_width=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,subwindow_number);
   chart_height=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,subwindow_number);
//--- Get the number of chart objects in the SUBWINDOW
   total_charts=ObjectsTotal(0,subwindow_number,OBJ_CHART);
//--- If there are no chart objects
   if(total_charts==0)
     {
      //--- Check if a time frame button has been clicked
      if(CheckClickOnTimeframeButton(clicked_object_name))
        {
         //--- Initialize the array of time frame buttons
         InitializeTimeframeButtonStates();
         //--- Get the time frame button text for the chart object tooltip
         object_text=ObjectGetString(0,clicked_object_name,OBJPROP_TEXT);
         //--- Get the time frame for the chart object
         tf=StringToTimeframe(object_text);
         //--- Set the chart object
         CreateChartInSubwindow(subwindow_number,0,0,chart_width,chart_height,
                                "chart_object_"+object_text,_Symbol,tf,chart_scale,
                                property_button_states[0],property_button_states[1],
                                property_button_states[2],property_button_states[3],
                                property_button_states[4],object_text);
         //--- Refresh the chart and exit
         ChartRedraw();
         return;
        }
     }
//--- If chart objects already exist in the SubWindow
   if(total_charts>0)
     {
      //--- Get the number of clicked time frame buttons and initialize the array of states
      int pressed_buttons_count=InitializeTimeframeButtonStates();
      //--- If there are no clicked buttons, delete the SubWindow
      if(pressed_buttons_count==0)
         DeleteSubwindow();
      //--- If the clicked buttons exist
      else
        {
         //--- Delete all chart objects from the subwindow
         ObjectsDeleteAll(0,subwindow_number,OBJ_CHART);
         //--- Get the width for chart objects
         chart_object_width=chart_width/pressed_buttons_count;
         //--- Iterate over all buttons in a loop
         for(int i=0; i<TIMEFRAME_BUTTONS; i++)
           {
            //--- If the button is clicked
            if(timeframe_button_states[i])
              {
               //--- Get the time frame button text for the chart object tooltip
               object_text=ObjectGetString(0,timeframe_button_names[i],OBJPROP_TEXT);
               //--- Get the time frame for the chart object
               tf=StringToTimeframe(object_text);
               //--- Set the chart object
               CreateChartInSubwindow(subwindow_number,x_distance,0,chart_object_width,chart_height,
                                      chart_object_names[i],_Symbol,tf,chart_scale,
                                      property_button_states[0],property_button_states[1],
                                      property_button_states[2],property_button_states[3],
                                      property_button_states[4],object_text);
               //--- Determine the X-coordinate for the next chart object
               x_distance+=chart_object_width;
              }
           }
        }
     }
//--- Refresh the chart
   ChartRedraw();
  }

Yukarıdaki kodda verilen ayrıntılı yorumlar, fonksiyon çalışmasını anlamanıza yardımcı olacaktır. Daha önce karşılaşmadığımız özel fonksiyonlar vurgulanmıştır.

InitializeTimeframeButtonStates() fonksiyonu tıklanan zaman aralığı düğmelerinin sayısını döndürür ve karşılık gelen durumların dizisini başlatır. Bu aynı zamanda düğme durumuna göre renkleri ayarlar:

//+------------------------------------------------------------------+
//| Initializing array of time frame button states and               |
//| returning the number of clicked buttons                          |
//+------------------------------------------------------------------+
int InitializeTimeframeButtonStates()
  {
//--- Counter of the clicked time frame buttons
   int pressed_buttons_count=0;
//--- Iterate over all time frame buttons and count the clicked ones
   for(int i=0; i<TIMEFRAME_BUTTONS; i++)
     {
      //--- If the button is clicked
      if(ObjectGetInteger(0,timeframe_button_names[i],OBJPROP_STATE))
        {
         //--- Indicate it in the current index of the array
         timeframe_button_states[i]=true;
         //--- Set clicked button colors
         ObjectSetInteger(0,timeframe_button_names[i],OBJPROP_COLOR,cOnButtonFont);
         ObjectSetInteger(0,timeframe_button_names[i],OBJPROP_BGCOLOR,cOnButtonBackground);
         //--- Increase the counter by one
         pressed_buttons_count++;
        }
      else
        {
         //--- Set unclicked button colors
         ObjectSetInteger(0,timeframe_button_names[i],OBJPROP_COLOR,cOffButtonFont);
         ObjectSetInteger(0,timeframe_button_names[i],OBJPROP_BGCOLOR,cOffButtonBackground);
         //--- Indicate that the button is unclicked
         timeframe_button_states[i]=false;
        }
     }
//--- Return the number of clicked buttons
   return(pressed_buttons_count);
  }

DeleteSubwindow() fonksiyonu oldukça basittir: grafikler için alt pencere varlığını kontrol eder ve bunu siler:

//+------------------------------------------------------------------+
//| Deleting subwindow for chart objects                             |
//+------------------------------------------------------------------+
void DeleteSubwindow()
  {
//--- If the SubWindow exists
   if((subwindow_number=ChartWindowFind(0,subwindow_shortname))>0)
     {
      //--- Delete it
      if(!ChartIndicatorDelete(0,subwindow_number,subwindow_shortname))
         Print("Failed to delete the "+subwindow_shortname+" indicator!");
     }
  }

Şimdi grafik nesnelerinin özelliklerine bakmalıyız. Diğer bir deyişle, ChartEventObjectClick() fonksiyonuna geri döneriz ve ToggleChartObjectProperty() fonksiyonunu değerlendiririz. Tıklanan nesnenin adı da buna aktarılır.

//+------------------------------------------------------------------+
//| Setting/deleting chart object property                           |
//| depending on the clicked button state                            |
//+------------------------------------------------------------------+
bool ToggleChartObjectProperty(string clicked_object_name)
  {

//--- If the "Date" button is clicked
   if(clicked_object_name=="property_button_date")
     {
      //--- If the button is clicked
      if(SetButtonColor(clicked_object_name))
         ShowDate(true);
      //--- If the button is unclicked
      else
         ShowDate(false);
      //--- Refresh the chart and exit
      ChartRedraw();
      return(true);
     }
//--- If the "Price" button is clicked
   if(clicked_object_name=="property_button_price")
     {
      //--- If the button is clicked
      if(SetButtonColor(clicked_object_name))
         ShowPrice(true);
      //--- If the button is unclicked
      else
         ShowPrice(false);
      //--- Refresh the chart and exit
      ChartRedraw();
      return(true);
     }
//--- If the "OHLC" button is clicked
   if(clicked_object_name=="property_button_ohlc")
     {
      //--- If the button is clicked
      if(SetButtonColor(clicked_object_name))
         ShowOHLC(true);
      //--- If the button is unclicked
      else
         ShowOHLC(false);
      //--- Refresh the chart and exit
      ChartRedraw();
      return(true);
     }
//--- If the "Ask/Bid" button is clicked
   if(clicked_object_name=="property_button_askbid")
     {
      //--- If the button is clicked
      if(SetButtonColor(clicked_object_name))
         ShowAskBid(true);
      //--- If the button is unclicked
      else
         ShowAskBid(false);
      //--- Refresh the chart and exit
      ChartRedraw();
      return(true);
     }
//--- If the "Trade Levels" button is clicked
   if(clicked_object_name=="property_button_trade_levels")
     {
      //--- If the button is clicked
      if(SetButtonColor(clicked_object_name))
         ShowTradeLevels(true);
      //--- If the button is unclicked
      else
         ShowTradeLevels(false);
      //--- Refresh the chart and exit
      ChartRedraw();
      return(true);
     }
//--- No matches
   return(false);
  }

Yukarıdaki kodda, tıklanan nesnenin adı, grafik özellikleri ile ilgili nesnenin adına göre sıralıdır. Bir eşleşme varsa, SetButtonColor() fonksiyonunda düğmeye tıklanıp tıklanmadığını kontrol ederiz ve ilgili düğme renklerini ayarlarız.

//+------------------------------------------------------------------+
//| Setting color of button elements depending on the state          |
//+------------------------------------------------------------------+
bool SetButtonColor(string clicked_object_name)
  {
//--- If the button is clicked
   if(ObjectGetInteger(0,clicked_object_name,OBJPROP_STATE))
     {
      //--- Set clicked button colors
      ObjectSetInteger(0,clicked_object_name,OBJPROP_COLOR,cOnButtonFont);
      ObjectSetInteger(0,clicked_object_name,OBJPROP_BGCOLOR,cOnButtonBackground);
      return(true);
     }
//--- If the button is unclicked
   if(!ObjectGetInteger(0,clicked_object_name,OBJPROP_STATE))
     {
      //--- Set unclicked button colors
      ObjectSetInteger(0,clicked_object_name,OBJPROP_COLOR,cOffButtonFont);
      ObjectSetInteger(0,clicked_object_name,OBJPROP_BGCOLOR,cOffButtonBackground);
      return(false);
     }
//---
   return(false);
  }

SetButtonColor() fonksiyonu düğme durumunu döndürür. Bu özniteliğe göre program, ilgili fonksiyonu, SubWindow içindeki tüm grafik nesnelerinde belirli bir özelliğin etkinleştirilmesi veya devre dışı bırakılması gerektiğine dair bilgilendirir. Bu, her bir özellik için yazılan ayrı bir fonksiyondur. İlgili fonksiyon kodları aşağıda verilmektedir:

//+------------------------------------------------------------------+
//| Enabling/disabling dates for all chart objects                   |
//+------------------------------------------------------------------+
void ShowDate(bool state)
  {
   int    total_charts =0;  // Number of objects
   string chart_name  =""; // Chart object name
//--- Check if the SubWindow exists
//    If it exists, then
   if((subwindow_number=ChartWindowFind(0,subwindow_shortname))>0)
     {
      //--- Get the number of chart objects
      total_charts=ObjectsTotal(0,subwindow_number,OBJ_CHART);
      //--- Iterate over all chart objects in a loop
      for(int i=0; i<total_charts; i++)
        {
         //--- Get the chart object name
         chart_name=ObjectName(0,i,subwindow_number,OBJ_CHART);
         //--- Set the property
         ObjectSetInteger(0,chart_name,OBJPROP_DATE_SCALE,state);
        }
      //--- Set the button state to the relevant index
      if(state)
         property_button_states[0]=true;
      else
         property_button_states[0]=false;
      //--- Refresh the chart
      ChartRedraw();
     }
  }
//+------------------------------------------------------------------+
//| Enabling/disabling prices for all chart objects                  |
//+------------------------------------------------------------------+
void ShowPrice(bool state)
  {
   int    total_charts =0;  // Number of objects
   string chart_name  =""; // Chart object name
//--- Check if the SubWindow exists
//    If it exists, then
   if((subwindow_number=ChartWindowFind(0,subwindow_shortname))>0)
     {
      //--- Get the number of chart objects
      total_charts=ObjectsTotal(0,subwindow_number,OBJ_CHART);
      //--- Iterate over all chart objects in a loop
      for(int i=0; i<total_charts; i++)
        {
         //--- Get the chart object name
         chart_name=ObjectName(0,i,subwindow_number,OBJ_CHART);
         //--- Set the property
         ObjectSetInteger(0,chart_name,OBJPROP_PRICE_SCALE,state);
        }
      //--- Set the button state to the relevant index
      if(state)
         property_button_states[1]=true;
      else
         property_button_states[1]=false;
      //--- Refresh the chart
      ChartRedraw();
     }
  }
//+------------------------------------------------------------------+
//| Enabling/disabling OHLC for all chart objects                    |
//+------------------------------------------------------------------+
void ShowOHLC(bool state)
  {
   int    total_charts =0;  // Number of objects
   long   subchart_id =0;  // Chart object identifier
   string chart_name  =""; // Chart object name
//--- Check if the SubWindow exists
//    If it exists, then
   if((subwindow_number=ChartWindowFind(0,subwindow_shortname))>0)
     {
      //--- Get the number of chart objects
      total_charts=ObjectsTotal(0,subwindow_number,OBJ_CHART);
      //--- Iterate over all chart objects in a loop
      for(int i=0; i<total_charts; i++)
        {
         //--- Get the chart object name
         chart_name=ObjectName(0,i,subwindow_number,OBJ_CHART);
         //--- Get the chart object identifier
         subchart_id=ObjectGetInteger(0,chart_name,OBJPROP_CHART_ID);
         //--- Set the property
         ChartSetInteger(subchart_id,CHART_SHOW_OHLC,state);
         //--- Refresh the chart object
         ChartRedraw(subchart_id);
        }
      //--- Set the button state to the relevant index
      if(state)
         property_button_states[2]=true;
      else
         property_button_states[2]=false;
      //--- Refresh the chart
      ChartRedraw();
     }
  }
//+------------------------------------------------------------------+
//| Enabling/disabling Ask/Bid levels for all chart objects          |
//+------------------------------------------------------------------+
void ShowAskBid(bool state)
  {
   int    total_charts =0;  // Number of objects
   long   subchart_id =0;  // Chart object identifier
   string chart_name  =""; // Chart object name
//--- Check if the SubWindow exists
//    If it exists, then
   if((subwindow_number=ChartWindowFind(0,subwindow_shortname))>0)
     {
      //--- Get the number of chart objects
      total_charts=ObjectsTotal(0,subwindow_number,OBJ_CHART);
      //--- Iterate over all chart objects in a loop
      for(int i=0; i<total_charts; i++)
        {
         //--- Get the chart object name
         chart_name=ObjectName(0,i,subwindow_number,OBJ_CHART);
         //--- Get the chart object identifier
         subchart_id=ObjectGetInteger(0,chart_name,OBJPROP_CHART_ID);
         //--- Set the properties
         ChartSetInteger(subchart_id,CHART_SHOW_ASK_LINE,state);
         ChartSetInteger(subchart_id,CHART_SHOW_BID_LINE,state);
         //--- Refresh the chart object
         ChartRedraw(subchart_id);
        }
      //--- Set the button state to the relevant index
      if(state)
         property_button_states[3]=true;
      else
         property_button_states[3]=false;
      //--- Refresh the chart
      ChartRedraw();
     }
  }
//+------------------------------------------------------------------+
//| Enabling/disabling trade levels for all chart objects            |
//+------------------------------------------------------------------+
void ShowTradeLevels(bool state)
  {
   int    total_charts =0;  // Number of objects
   long   subchart_id =0;  // Chart object identifier
   string chart_name  =""; // Chart object name
//--- Check if the SubWindow exists
//    If it exists, then
   if((subwindow_number=ChartWindowFind(0,subwindow_shortname))>0)
     {
      //--- Get the number of chart objects
      total_charts=ObjectsTotal(0,subwindow_number,OBJ_CHART);
      //--- Iterate over all chart objects in a loop
      for(int i=0; i<total_charts; i++)
        {
         //--- Get the chart object name
         chart_name=ObjectName(0,i,subwindow_number,OBJ_CHART);
         //--- Get the chart object identifier
         subchart_id=ObjectGetInteger(0,chart_name,OBJPROP_CHART_ID);
         //--- Set the property
         ChartSetInteger(subchart_id,CHART_SHOW_TRADE_LEVELS,state);
         //--- Refresh the chart object
         ChartRedraw(subchart_id);
        }
      //--- Set the button state to the relevant index
      if(state)
         property_button_states[4]=true;
      else
         property_button_states[4]=false;
      //--- Refresh the chart
      ChartRedraw();
     }
  }

Artık, fonksiyonların tamamı panel ile etkileşim için hazırdır. Sadece ana OnChartEvent() fonksiyonuna kodun bir dizesini eklememiz gerekiyor:

//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--- The CHARTEVENT_OBJECT_CLICK event
   if(ChartEventObjectClick(id,lparam,dparam,sparam))
      return;

  }

Gösterge derlenirse ve grafikte şimdi çalıştırılırsa, ilgili zaman aralığı düğmelerine tıklandığında grafik nesneleri alt pencereye eklenecektir. Ayrıca, özelliklerin düğmelerinden herhangi birine tıklarsak, grafik nesnelerindeki ilgili değişiklikleri görebiliriz:

Şekil 5. Belirtilen özelliklere sahip grafik nesnelerini ekleme

Şekil 5. Belirtilen özelliklere sahip grafik nesnelerini ekleme

Ancak, grafik penceresi veya alt pencere yeniden boyutlandırılırsa, grafik nesnesinin boyutları buna göre ayarlanmayacaktır. Şimdi sıra CHARTEVENT_CHART_CHANGE olayında.

Tıpkı "grafik nesnesine tıklama" olayını takip ederken ChartEventObjectClick() fonksiyonunu oluşturduğumuz gibi, şimdi ChartEventChartChange() fonksiyonunu yazacağız:

//+------------------------------------------------------------------+
//| Event of modifying the chart properties                          |
//+------------------------------------------------------------------+
bool ChartEventChartChange(int id,
                           long lparam,
                           double dparam,
                           string sparam)
  {
//--- Chart has been resized or the chart properties have been modified
   if(id==CHARTEVENT_CHART_CHANGE)
     {
      //--- If the SubWindow has been deleted (or does not exist), while the time frame buttons are clicked, 
      //    release all the buttons (reset)
      if(OnSubwindowDelete())
         return(true);
      //--- Save the height and width values of the main chart and SubWindow, if it exists
      GetSubwindowWidthAndHeight();
      //--- Adjust the sizes of chart objects
      AdjustChartObjectsSizes();
      //--- Refresh the chart and exit
      ChartRedraw();
      return(true);
     }
//---
   return(false);
  }

Program ana grafik boyutunun veya özelliklerinin değiştirildiğini belirlemişse, SubWindow öğesinin silinip silinmediğini kontrol etmek için ilk olarak OnSubwindowDelete() fonksiyonunu kullanırız. Alt pencere bulunamazsa, panel sıfırlanır.

//+------------------------------------------------------------------+
//| Response to Subwindow deletion                                   |
//+------------------------------------------------------------------+
bool OnSubwindowDelete()
  {
//--- if there is no SubWindow
   if(ChartWindowFind(0,subwindow_shortname)<1)
     {
      //--- Reset the panel with time frame buttons
      AddTimeframeButtons();
      ChartRedraw();
      return(true);
     }
//--- SubWindow exists
   return(false);
  }

Alt pencere olması gereken yerdeyse, alt pencere genişlik ve yükseklik değerleri GetSubwindowWidthAndHeight() fonksiyonundaki global değişkenlere atanır:

//+------------------------------------------------------------------+
//| Saving the SubWindow height and width values                     |
//+------------------------------------------------------------------+
void GetSubwindowWidthAndHeight()
  {
//--- Check if there is a subwindow named SubWindow
   if((subwindow_number=ChartWindowFind(0,subwindow_shortname))>0)
     {
      // Get the subwindow height and width
      chart_height=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,subwindow_number);
      chart_width=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,subwindow_number);
     }
  }

Ve son olarak grafik nesnelerinin boyutları AdjustChartObjectsSizes() fonksiyonunda ayarlanır:

//+------------------------------------------------------------------+
//| Adjusting width of chart objects when modifying the window width |
//+------------------------------------------------------------------+
void AdjustChartObjectsSizes()
  {
   int             x_distance         =0;           // X-coordinate
   int             total_objects      =0;           // Number of chart objects
   int             chart_object_width =0;           // Chart object width
   string          object_name        ="";          // Object name
   ENUM_TIMEFRAMES TF                 =WRONG_VALUE; // Time frame
//--- Get the SubWindow number
   if((subwindow_number=ChartWindowFind(0,subwindow_shortname))>0)
     {
      //--- Get the total number of chart objects
      total_objects=ObjectsTotal(0,subwindow_number,OBJ_CHART);
      //--- If there are no objects, delete the subwindow and exit
      if(total_objects==0)
        {
         DeleteSubwindow();
         return;
        }
      //--- Get the width for chart objects
      chart_object_width=chart_width/total_objects;
      //--- Iterate over all chart objects in a loop
      for(int i=total_objects-1; i>=0; i--)
        {
         //--- Get the name
         object_name=ObjectName(0,i,subwindow_number,OBJ_CHART);
         //--- Set the chart object width and height
         ObjectSetInteger(0,object_name,OBJPROP_YSIZE,chart_height);
         ObjectSetInteger(0,object_name,OBJPROP_XSIZE,chart_object_width);
         //--- Set the chart object position
         ObjectSetInteger(0,object_name,OBJPROP_YDISTANCE,0);
         ObjectSetInteger(0,object_name,OBJPROP_XDISTANCE,x_distance);
         //--- Set the new X-coordinate for the next chart object
         x_distance+=chart_object_width;
        }
     }
  }

Ana grafiğin boyutunun ve özelliklerinin değiştirilmesini olayını takip etmek için, OnChartEvent() fonksiyonuna aşağıdaki dize eklenmelidir:

Göstergenin derlenmesinin ve bunun grafiğe eklenmesinin ardından, grafik nesnelerinin ana pencere her yeniden boyutlandırıldığında alt pencere boyutuna göre ayarlandığını göreceksiniz.

 

Sonuç

Makaleyi burada sonlandıralım. Ev ödevi olarak, ana grafikteki sembol değiştirildiğinde grafik nesnelerindeki sembollerin ayarlanması için bu özelliği uygulamaya çalışın. Ayrıca, düşükten yükseğe (soldan sağa) sıralı olarak ayarlanan grafik nesnelerinde zaman aralıkları bulunmasını da isteyebilirsiniz. Bu imkan, yukarıda açıklanan gösterge sürümünde uygulanmamıştır.

Hazır TF PANEL uygulamasının açıklamasında, bu özelliklerin uygulanmasını gösteren bir video bulabilirsiniz. Kaynak kodu dosyaları makaleye eklenmiştir ve buradan indirilebilir.

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

Ekli dosyalar |
subwindow.mq5 (1.55 KB)
chartobjects.mq5 (39.85 KB)
MQL5 Tarif Defteri Gösterge Alt Pencere Kontrolleri - Düğmeler MQL5 Tarif Defteri Gösterge Alt Pencere Kontrolleri - Düğmeler
Bu makalede, düğme kontrolleri ile bir kullanıcı arayüzünü geliştirme örneğini ele alacağız. Kullanıcı ile etkileşim fikrini iletmek için, imleç üzerlerine geldiğinde düğmelerin renkleri değişecektir. İmleç bir düğmenin üzerindeyken, düğme rengi hafifçe koyulaşacak ve düğmeye tıklandığında büyük ölçüde koyulaşacaktır. Ayrıca, her düğmeye araç ipuçları ekleyerek sezgisel bir arayüz oluşturacağız.
MQL5 Tarif Defteri MetaTrader 5 Alım Satım Olayları için Sesli Bildirimler MQL5 Tarif Defteri MetaTrader 5 Alım Satım Olayları için Sesli Bildirimler
Bu makalede, Uzman Danışmanın dosyasına ses dosyaları eklenmesi ve böylece alım satım olaylarına sesli bildirimler eklenmesi gibi konuları ele alacağız. Dosyaların eklenmesi, ses dosyalarının Uzman Danışman içine yerleştirileceği anlamına gelir. Bu nedenle, Uzman Danışmanın derlenmiş sürümünü (*.ex5) başka bir kullanıcıya sağlarken, ses dosyalarını da sağlamanız ve nereye kaydedilmeleri gerektiğini açıklamanız gerekmez.
MQL5 Tarif Defteri Gösterge Alt Pencere Kontrolleri - Kaydırma Çubuğu MQL5 Tarif Defteri Gösterge Alt Pencere Kontrolleri - Kaydırma Çubuğu
Çeşitli kontrolleri keşfetmeye devam edelim ve bu sefer dikkatimizi kaydırma çubuğuna çevirelim. Tıpkı "MQL5 Tarif Defteri: Gösterge Alt Pencere Kontrolleri - Düğmeler" başlıklı önceki makaledeki gibi, tüm işlemler gösterge alt penceresinde gerçekleştirilecektir. OnChartEvent() fonksiyonundaki olaylar ile çalışmanın ayrıntılı bir açıklamasını sağladığından, yukarıda bahsedilen makaleyi okumak için biraz zaman ayırın, ancak bu noktaya bu makalede yalnızca üstünkörü değinilecektir. Açıklayıcı olması açısından, bu sefer MQL5 kaynakları kullanılarak elde edilebilen tüm finansal enstrüman özelliklerinin geniş bir listesi için dikey bir kaydırma çubuğu oluşturacağız.
MQL5 Tarif Defteri Uzman Danışmanın Belirlenen Kriterlere Göre Optimizasyon Sonuçlarını Kaydetme MQL5 Tarif Defteri Uzman Danışmanın Belirlenen Kriterlere Göre Optimizasyon Sonuçlarını Kaydetme
MQL5 programlamasına dair makaleler serisine devam ediyoruz. Bu sefer, Uzman Danışman parametre optimizasyonu sırasında her bir optimizasyon doğru geçişinin sonucunun nasıl elde edileceğini göreceğiz. Uygulama, harici parametrelerde belirtilen koşulların sağlanması durumunda ilgili geçiş değerlerinin bir dosyaya yazılmasını sağlayacak şekilde yapılacaktır. Test değerlerine ek olarak, bu sonuçlara neden olan parametreleri de kaydedeceğiz.