English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
MQL5 Tarif Defteri Özel Bilgi Panelindeki Pozisyon Özellikleri

MQL5 Tarif Defteri Özel Bilgi Panelindeki Pozisyon Özellikleri

MetaTrader 5Örnekler | 13 Ocak 2022, 09:29
56 0
Anatoli Kazharski
Anatoli Kazharski

Giriş

Bu defa, mevcut sembol üzerindeki pozisyon özelliklerini elde ederek manuel alım satım sırasında bunları özel bilgi panelinde gösterecek basit bir Uzman Danışman oluşturacağız. Bilgi paneli, grafik nesneler kullanılarak oluşturulacak ve her tikte görüntülenen bilgiler yenilenecektir. Bu, aşağıdaki serinin önceki makalesinde açıklanan betiği manuel olarak çalıştırmak zorunda kalmaktan çok daha uygun olacaktır: "MQL5 Tarif Defteri: Pozisyon Özelliklerini Elde Etme"

 

Bir Uzman Danışman Geliştirme

Grafik nesneleri ile başlayalım. Bilgi paneli oluşturmak için, pozisyon özelliklerinin arka planı, başlığı, adları ve değerleri için nesnelere ihtiyacımız var. Arka plan ve başlık, fiyatla birlikte hareket etmeyen bir dikdörtgen gerektirecektir. Dikdörtgen, Dikdörtgen Etiketi veya Düzenle gibi grafik nesneleri kullanılarak oluşturulabilirken, nesne özelliklerinin adları ve değerleri Metin Etiketleri kullanılarak oluşturulacaktır.

Koda devam etmeden önce ilk olarak bilgi paneli için bir düzen hazırlayacağız. Bunun kolaylığı, ayarlar penceresindeki herhangi bir özelliği hızla değiştirebilmemize ve bilgi panelinin görünümünü özelleştirebilmemize dayanır.

Her nesnenin, seçilen bir nesnenin içerik menüsünden açılabilen bir ayarlar penceresi vardır. Ayarlar penceresi, Nesne Listesi(Ctrl+B) seçeneğinden gerekli nesne seçilerek ve Özellikler seçeneğine tıklanarak da açılabilir. Bilgi paneli düzeni aşağıda gösterilmiştir. Bu, kod yazarken boyutları ve koordinatları tahmin etmek için de kullanılabilir. Bilgi panelinin kodu hazır olduğunda, Uzman Danışman bunları "göremeyeceğinden" ve dolayısıyla bunları grafikten çıkaramayacağından, düzen nesnelerini manuel olarak silmeniz gerekecektir.

Şekil 1. Bilgi paneli düzeninin hazırlanması.

Şekil 1. Bilgi paneli düzeninin hazırlanması.

Şimdi Uzman Danışman için bir şablon oluşturmamız gerekiyor. Bu, betik için olduğu kadar hızlı bir şekilde yapılabilir. MQL5 Sihirbazında, Uzman Danışman (şablon) seçeneği varsayılan olarak seçilmiştir. Bu sefer ihtiyaç duyulmadığı için seçeneklerde herhangi bir değişiklik yapmadan sonraki adımlara geçiyoruz. Ardından Bitir seçeneğine tıklayın, aşağıdaki gibi bir şablon göreceksiniz:

//+------------------------------------------------------------------+
//|                                      PositionPropertiesPanel.mq5 |
//|                        Copyright 2012, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2012, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+

Uzman Danışman şablonunun betik şablonundan farklı olduğu hemen fark edilebilir. Program özellikleri (#property) dışında üç ana fonksiyon vardır: OnInit(), OnDeinit() ve OnTick().

OnInit() fonksiyonu program yüklenirken, harici parametreleri değiştirirken, programın o anda grafiğe eklenmesi şartıyla programı derlerken ve sembol veya nokta değiştirilirken çağrılır. Gerekirse, daha sonra bunlarla çalışabilmek için bu fonksiyondaki belirli değişkenleri veya dizileri başlatabilirsiniz.

OnDeinit() fonksiyonu, programı çizelgeden sildiğinizde ve hesabı, sembolü veya dönemi değiştirdiğinizde çağrılır. Tüm olası sonlandırma nedenleri MQL5 Referansı belgesinde verilmiştir. Bu Uzman Danışman, sonlandırma nedeni tanımlayıcısını (OnDeinit() fonksiyon parametresi) metne dönüştüren GetDeinitReasonText() adlı kullanıcı tanımlı fonksiyonu kullanır.

Ve son olarak, OnTick() fonksiyonu. Uzman Danışmanın şu anda çalışmakta olduğu grafikte yer alan sembolde her yeni tik olduğunda çağrılır.

Şimdi Uzman Danışmanda kullanacağımız tüm sabitleri, değişkenleri ve dizileri hazırlayalım. Bunları programın en başına yerleştireceğiz. İlk olarak, değerleri program boyunca değişmeyen değişkenleri tanımlayın:

//---
#define INFOPANEL_SIZE 14 // Size of the array for info panel objects
#define EXPERT_NAME MQL5InfoString(MQL5_PROGRAM_NAME) // Name of the Expert Advisor
//---

Bunun ardından pozisyon özellikleri için global değişkenler gelir:

//--- GLOBAL VARIABLES
bool                 pos_open=false;         // Flag of presence/absence of an open position
string               pos_symbol="";          // Symbol
long                 pos_magic=0;            // Magic number
string               pos_comment="";         // Comment
double               pos_swap=0.0;           // Swap
double               pos_commission=0.0;     // Commission
double               pos_price=0.0;          // Position price
double               pos_cprice=0.0;         // Current price of the position
double               pos_profit=0.0;         // Profit/Loss of the position
double               pos_volume=0.0;         // Position volume
double               pos_sl=0.0;             // Stop Loss of the position
double               pos_tp=0.0;             // Take Profit of the position
datetime             pos_time=NULL;          // Position opening time
long                 pos_id=0;               // Position identifier
ENUM_POSITION_TYPE   pos_type=WRONG_VALUE;   // Position type

Değişkenlerden sonra, grafik nesnesi isimlerinin dizilerini bildireceğiz. Bu nesneler, pozisyon özelliklerini ve değerlerini grafikte gösterecektir. Bunun için, iki dize dizisi oluşturacağız ve öğelerini hemen değerlere başlatacağız. Köşeli parantezlerde, programın hemen başında bildirilen INFOPANEL_SIZE sabitinin değerini kullanırız. Yani her dizide 14 öğe olacaktır.

// Array of names of objects that display names of position properties
string positionPropertyNames[INFOPANEL_SIZE]=
  {
   "name_pos_symbol",
   "name_pos_magic",
   "name_pos_comment",
   "name_pos_swap",
   "name_pos_commission",
   "name_pos_price",
   "name_pos_cprice",
   "name_pos_profit",
   "name_pos_volume",
   "name_pos_sl",
   "name_pos_tp",
   "name_pos_time",
   "name_pos_id",
   "name_pos_type"
  };
//---
// Array of names of objects that display values of position properties
string positionPropertyValues[INFOPANEL_SIZE]=
  {
   "value_pos_symbol",
   "value_pos_magic",
   "value_pos_comment",
   "value_pos_swap",
   "value_pos_commission",
   "value_pos_price",
   "value_pos_cprice",
   "value_pos_profit",
   "value_pos_volume",
   "value_pos_sl",
   "value_pos_tp",
   "value_pos_time",
   "value_pos_id",
   "value_pos_type"
  };
//---

Bu adları kullanarak, grafikte gerekli nesneyi programlı olarak bulabilir ve görüntülenen metin, renk, boyut vb. özelliklerini ayarlayabilir veya değiştirebilirsiniz. Bu adlar grafikte oluşturulduktan sonra Nesne Listesi (Ctrl+B) penceresinde de görüntülenecektir. Ancak MQL5 programı tarafından oluşturulan nesneler varsayılan olarak gizlendiğinden bunları göremezsiniz. Bunları görünür yapmak için, Nesne Listesi penceresinde Tümünü Listele seçeneğine tıklamalısınız. Bu özellik, manuel olarak oluşturulan nesneleri programlı olarak oluşturulanlardan ayırmaya yardımcı olur ve bu kuşkusuz çok işimize gelir.

Ayrıca, grafik nesneleri oluşturmak için Uzman Danışman tarafından kullanılacak kullanıcı tanımlı fonksiyonlara ihtiyacımız olacaktır. MQL5 tarafından grafik nesnelerin oluşturulması için sunulan fonksiyon ObjectCreate() fonksiyonudur. Ancak, nesne özelliklerini de ayarlamamız gerektiğinden, nesnelerin kendilerinin birden fazla kez oluşturulması gerekebileceğinden, tek bir kod satırında uygulanabilecek daha kullanışlı ve kompakt bir yöntem düşünmek daha iyi olacaktır.

Bilgi paneli arka planını ve başlığını oluşturmak için Düzenle grafik nesnesini kullanacağız. CreateEdit() fonksiyonunu yazalım:

//+------------------------------------------------------------------+
//| CREATING THE EDIT OBJECT                                         |
//+------------------------------------------------------------------+
void CreateEdit(long             chart_id,         // chart id
                int              sub_window,       // (sub)window number
                string           name,             // object name
                string           text,             // displayed text
                ENUM_BASE_CORNER corner,           // chart corner
                string           font_name,        // font
                int              font_size,        // font size
                color            font_color,       // font color
                int              x_size,           // width
                int              y_size,           // height
                int              x_distance,       // X-coordinate
                int              y_distance,       // Y-coordinate
                long             z_order,          // Z-order
                color            background_color, // background color
                bool             read_only)        // Read Only flag
  {
// If the object has been created successfully,...
   if(ObjectCreate(chart_id,name,OBJ_EDIT,sub_window,0,0))
     {
      // ...set its properties
      ObjectSetString(chart_id,name,OBJPROP_TEXT,text);                 // displayed text
      ObjectSetInteger(chart_id,name,OBJPROP_CORNER,corner);            // set the chart corner
      ObjectSetString(chart_id,name,OBJPROP_FONT,font_name);            // set the font
      ObjectSetInteger(chart_id,name,OBJPROP_FONTSIZE,font_size);       // set the font size
      ObjectSetInteger(chart_id,name,OBJPROP_COLOR,font_color);         // font color
      ObjectSetInteger(chart_id,name,OBJPROP_BGCOLOR,background_color); // background color
      ObjectSetInteger(chart_id,name,OBJPROP_XSIZE,x_size);             // width
      ObjectSetInteger(chart_id,name,OBJPROP_YSIZE,y_size);             // height
      ObjectSetInteger(chart_id,name,OBJPROP_XDISTANCE,x_distance);     // set the X coordinate
      ObjectSetInteger(chart_id,name,OBJPROP_YDISTANCE,y_distance);     // set the Y coordinate
      ObjectSetInteger(chart_id,name,OBJPROP_SELECTABLE,false);         // cannot select the object if FALSE
      ObjectSetInteger(chart_id,name,OBJPROP_ZORDER,z_order);           // Z-order of the object
      ObjectSetInteger(chart_id,name,OBJPROP_READONLY,read_only);       // Read Only
      ObjectSetInteger(chart_id,name,OBJPROP_ALIGN,ALIGN_LEFT);         // align left
      ObjectSetString(chart_id,name,OBJPROP_TOOLTIP,"\n");              // no tooltip if "\n"
     }
  }

Artık Düzenle (OBJ_EDIT) grafik nesnesi tek bir kod satırı kullanılarak oluşturulabilir. Grafik üzerinde bilgi panelini ayarlayacak bir fonksiyon oluştururken bunu bir örnekle göstereceğiz.

Şimdi pozisyon özellikleri listesini ve değerlerini görüntülemek için kullanılacak Text Label nesnelerine geçelim ve CreateLabel() fonksiyonunu benzer şekilde oluşturalım:

//+------------------------------------------------------------------+
//| CREATING THE LABEL OBJECT                                        |
//+------------------------------------------------------------------+
void CreateLabel(long               chart_id,   // chart id
                 int                sub_window, // (sub)window number
                 string             name,       // object name
                 string             text,       // displayed text
                 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
                 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_LABEL,sub_window,0,0))
     {
      // ...set its properties
      ObjectSetString(chart_id,name,OBJPROP_TEXT,text);              // displayed text
      ObjectSetString(chart_id,name,OBJPROP_FONT,font_name);         // set the font
      ObjectSetInteger(chart_id,name,OBJPROP_COLOR,font_color);      // set the font color
      ObjectSetInteger(chart_id,name,OBJPROP_ANCHOR,anchor);         // set the anchor point
      ObjectSetInteger(chart_id,name,OBJPROP_CORNER,corner);         // set the chart corner
      ObjectSetInteger(chart_id,name,OBJPROP_FONTSIZE,font_size);    // set the font size
      ObjectSetInteger(chart_id,name,OBJPROP_XDISTANCE,x_distance);  // set the X-coordinate
      ObjectSetInteger(chart_id,name,OBJPROP_YDISTANCE,y_distance);  // set the Y-coordinate
      ObjectSetInteger(chart_id,name,OBJPROP_SELECTABLE,false);      // cannot select the object if FALSE
      ObjectSetInteger(chart_id,name,OBJPROP_ZORDER,z_order);        // Z-order of the object
      ObjectSetString(chart_id,name,OBJPROP_TOOLTIP,"\n");           // no tooltip if "\n"
     }
  }

MQL5 Referansı içindeki fonksiyon açıklamalarına bakmanız da tavsiye edilir.

Grafikten silme işleminde, Uzman Danışman daha önce grafiğe eklediği tüm nesneleri sırayla silmelidir. Bunun için, sadece nesne adını DeleteObjectByName() fonksiyona aktarabilirsiniz. Bu durumda Uzman Danışman, nesneyi belirtilen ada göre arar ve nesne bulunursa, nesneyi arayan yerleşik ObjectFind() fonksiyonunu ve ObjectDelete() fonksiyonunu kullanarak nesneyi siler.

//+------------------------------------------------------------------+
//| DELETING THE OBJECT BY NAME                                      |
//+------------------------------------------------------------------+
void DeleteObjectByname(string name)
  {
   int  sub_window=0;      // Returns the number of the subwindow where the object is located
   bool res       =false;  // Result following an attempt to delete the object
//--- Find the object by name
   sub_window=ObjectFind(ChartID(),name);
//---
   if(sub_window>=0) // If it has been found,..
     {
      res=ObjectDelete(ChartID(),name); // ...delete it
      //---
      // If an error occurred when deleting the object,..
      if(!res) // ...print the relevant message
        {
         Print("Error deleting the object: ("+IntegerToString(GetLastError())+"): "+ErrorDescription(GetLastError()));
        }
     }
  }

DeleteObjectByName() fonksiyonunda, bir nesneyi silerken hata kontrolü de uygularız. Bir hata oluşursa, hata kodunu ve açıklamasını içeren ilgili bir mesaj görünecektir. Yukarıdaki kodda görebileceğiniz gibi, hata kodunu metin açıklamasına dönüştüren kullanıcı tanımlı ek bir fonksiyon kullanırız: ErrorDescription() fonksiyonu. Çok sayıda hata kodu olduğu için yukarıdakileri bu fonksiyonun sadece bir kısmını kullanarak örneklendireceğim (aşağıdaki koda bakınız). Kodun tam sürümü bu makaleye eklenmiş kaynak kod dosyasında bulunabilir.

//+------------------------------------------------------------------+
//| RETURNING THE ERROR DESCRIPTION                                  |
//+------------------------------------------------------------------+
string ErrorDescription(int error_code)
  {
   string error_string="";
//---
   switch(error_code)
     {
      //--- Trade server return codes

      case 10004: error_string="Requote";                                                                break;
      case 10006: error_string="Request rejected";                                                       break;
      case 10007: error_string="Request canceled by trader";                                             break;
      case 10008: error_string="Order placed";                                                           break;
      case 10009: error_string="Request executed";                                                       break;
      case 10010: error_string="Request executed partially";                                             break;
      case 10011: error_string="Request processing error";                                               break;
      case 10012: error_string="Request timed out";                                                      break;
      case 10013: error_string="Invalid request";                                                        break;
      case 10014: error_string="Invalid request volume";                                                 break;
      case 10015: error_string="Invalid request price";                                                  break;
      case 10016: error_string="Invalid Stop orders in the request";                                     break;
      case 10017: error_string="Trading forbidden";                                                      break;
      case 10018: error_string="Market is closed";                                                       break;
      case 10019: error_string="Insufficient funds";                                                     break;
      case 10020: error_string="Prices changed";                                                         break;
      case 10021: error_string="No quotes to process the request";                                       break;
      case 10022: error_string="Invalid order expiration in the request";                                break;
      case 10023: error_string="Order status changed";                                                   break;
      case 10024: error_string="Too many requests";                                                      break;
      case 10025: error_string="No changes in the request";                                              break;
      case 10026: error_string="Automated trading is disabled by trader";                                break;
      case 10027: error_string="Automated trading is disabled by the client terminal";                   break;
      case 10028: error_string="Request blocked for processing";                                         break;
      case 10029: error_string="Order or position frozen";                                               break;
      case 10030: error_string="The specified type of order execution by balance is not supported";      break;
      case 10031: error_string="No connection with trade server";                                        break;
      case 10032: error_string="Transaction is allowed for live accounts only";                          break;
      case 10033: error_string="You have reached the maximum number of pending orders";                  break;
      case 10034: error_string="You have reached the maximum order and position volume for this symbol"; break;

      ...

     }
//---
   return(error_string);
  }

Önceki makalede, pozisyon özelliklerini elde eden GetPositionProperties() fonksiyonundan bahsetmiştik. Bu sefer fonksiyon yapısı biraz daha karmaşık olacak. mevcut olarak açık olan bir pozisyonu, pos_open global değişkeninde saklanan bir açık pozisyonun varlığı/yokluğu bayrağıyla kontrol edeceğiz. Bu bilgi, her seferinde PositionSelect() fonksiyonunu çağırmak zorunda kalmadan diğer fonksiyonlarda da gerekli olabilir.

Daha sonra, açık bir pozisyon varsa bunun özelliklerini elde edeceğiz, aksi takdirde tüm değişkenler sıfırlanacaktır. Şimdi basit bir ZeroPositionProperties() fonksiyonu yazalım:

//+------------------------------------------------------------------+
//| ZEROING OUT VARIABLES FOR POSITION PROPERTIES                    |
//+------------------------------------------------------------------+
void ZeroPositionProperties()
  {
   pos_symbol     ="";
   pos_comment    ="";
   pos_magic      =0;
   pos_price      =0.0;
   pos_cprice     =0.0;
   pos_sl         =0.0;
   pos_tp         =0.0;
   pos_type       =WRONG_VALUE;
   pos_volume     =0.0;
   pos_commission =0.0;
   pos_swap       =0.0;
   pos_profit     =0.0;
   pos_time       =NULL;
   pos_id         =0;
  }

Ayrıca, GetPositionProperties() fonksiyonunun sonunda, grafikteki bilgi panelini çizen/güncelleyen kullanıcı tanımlı bir SetInfoPanel() fonksiyonunu çağıracağız.

//+------------------------------------------------------------------+
//| GETTING POSITION PROPERTIES                                      |
//+------------------------------------------------------------------+
void GetPositionProperties()
  {
// Check if there is an open position
   pos_open=PositionSelect(_Symbol);
//---
   if(pos_open) // If an open position exists, get its properties
     {
      pos_symbol     =PositionGetString(POSITION_SYMBOL);
      pos_comment    =PositionGetString(POSITION_COMMENT);
      pos_magic      =PositionGetInteger(POSITION_MAGIC);
      pos_price      =PositionGetDouble(POSITION_PRICE_OPEN);
      pos_cprice     =PositionGetDouble(POSITION_PRICE_CURRENT);
      pos_sl         =PositionGetDouble(POSITION_SL);
      pos_tp         =PositionGetDouble(POSITION_TP);
      pos_type       =(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
      pos_volume     =PositionGetDouble(POSITION_VOLUME);
      pos_commission =PositionGetDouble(POSITION_COMMISSION);
      pos_swap       =PositionGetDouble(POSITION_SWAP);
      pos_profit     =PositionGetDouble(POSITION_PROFIT);
      pos_time       =(datetime)PositionGetInteger(POSITION_TIME);
      pos_id         =PositionGetInteger(POSITION_IDENTIFIER);
     }
   else // If there is no open position, zero out variables for position properties
      ZeroPositionProperties();
//---
   SetInfoPanel(); // Set/update the info panel
  }

Şimdi SetInfoPanel() fonksiyonunu yazalım. Aşağıda, detaylı yorumlar içeren fonksiyon kodu yer almaktadır:

//+------------------------------------------------------------------+
//| SETTING THE INFO PANEL                                           |
//|------------------------------------------------------------------+
void SetInfoPanel()
  {
   int               y_bg=18;             // Y-coordinate for the background and header
   int               y_property=32;       // Y-coordinate for the list of properties and their values
   int               line_height=12;      // Line height
//---
   int               font_size=8;         // Font size
   string            font_name="Calibri"; // Font
   color             font_color=clrWhite; // Font color
//---
   ENUM_ANCHOR_POINT anchor=ANCHOR_RIGHT_UPPER; // Anchor point in the top right corner
   ENUM_BASE_CORNER  corner=CORNER_RIGHT_UPPER; // Origin of coordinates in the top right corner of the chart
//--- X-coordinates
   int               x_first_column=120// First column (names of properties)
   int               x_second_column=10;  // Second column (values of properties)
//--- Array of Y-coordinates for the names of position properties and their values
   int               y_prop_array[INFOPANEL_SIZE]={0};
//--- Fill the array with coordinates for each line on the info panel
   y_prop_array[0]=y_property;
   y_prop_array[1]=y_property+line_height;
   y_prop_array[2]=y_property+line_height*2;
   y_prop_array[3]=y_property+line_height*3;
   y_prop_array[4]=y_property+line_height*4;
   y_prop_array[5]=y_property+line_height*5;
   y_prop_array[6]=y_property+line_height*6;
   y_prop_array[7]=y_property+line_height*7;
   y_prop_array[8]=y_property+line_height*8;
   y_prop_array[9]=y_property+line_height*9;
   y_prop_array[10]=y_property+line_height*10;
   y_prop_array[11]=y_property+line_height*11;
   y_prop_array[12]=y_property+line_height*12;
   y_prop_array[13]=y_property+line_height*13;
//--- Background of the info panel
   CreateEdit(0,0,"InfoPanelBackground","",corner,font_name,8,clrWhite,230,190,231,y_bg,0,C'15,15,15',true);
//--- Header of the info panel
   CreateEdit(0,0,"InfoPanelHeader","POSITION PROPERTIES",corner,font_name,8,clrWhite,230,14,231,y_bg,1,clrFireBrick,true);
//--- List of the names of position properties and their values
//    Property name
   CreateLabel(0,0,pos_prop_names[0],"Symbol :",anchor,corner,font_name,font_size,font_color,x_first_column,y_prop_array[0],2);
//    Property value
   CreateLabel(0,0,pos_prop_values[0],GetValInfoPanel(0),anchor,corner,font_name,font_size,font_color,x_second_column,y_prop_array[0],2);
//---
   CreateLabel(0,0,pos_prop_names[1],"Magic Number :",anchor,corner,font_name,font_size,font_color,x_first_column,y_prop_array[1],2);
   CreateLabel(0,0,pos_prop_values[1],GetValInfoPanel(1),anchor,corner,font_name,font_size,font_color,x_second_column,y_prop_array[1],2);
//---
   CreateLabel(0,0,pos_prop_names[2],"Comment :",anchor,corner,font_name,font_size,font_color,x_first_column,y_prop_array[2],2);
   CreateLabel(0,0,pos_prop_values[2],GetValInfoPanel(2),anchor,corner,font_name,font_size,font_color,x_second_column,y_prop_array[2],2);
//---
   CreateLabel(0,0,pos_prop_names[3],"Swap :",anchor,corner,font_name,font_size,font_color,x_first_column,y_prop_array[3],2);
   CreateLabel(0,0,pos_prop_values[3],GetValInfoPanel(3),anchor,corner,font_name,font_size,font_color,x_second_column,y_prop_array[3],2);
//---
   CreateLabel(0,0,pos_prop_names[4],"Commission :",anchor,corner,font_name,font_size,font_color,x_first_column,y_prop_array[4],2);
   CreateLabel(0,0,pos_prop_values[4],GetValInfoPanel(4),anchor,corner,font_name,font_size,font_color,x_second_column,y_prop_array[4],2);
//---
   CreateLabel(0,0,pos_prop_names[5],"Open Price :",anchor,corner,font_name,font_size,font_color,x_first_column,y_prop_array[5],2);
   CreateLabel(0,0,pos_prop_values[5],GetValInfoPanel(5),anchor,corner,font_name,font_size,font_color,x_second_column,y_prop_array[5],2);
//---
   CreateLabel(0,0,pos_prop_names[6],"Current Price :",anchor,corner,font_name,font_size,font_color,x_first_column,y_prop_array[6],2);
   CreateLabel(0,0,pos_prop_values[6],GetValInfoPanel(6),anchor,corner,font_name,font_size,font_color,x_second_column,y_prop_array[6],2);
//---
   CreateLabel(0,0,pos_prop_names[7],"Profit :",anchor,corner,font_name,font_size,font_color,x_first_column,y_prop_array[7],2);
   CreateLabel(0,0,pos_prop_values[7],GetValInfoPanel(7),anchor,corner,font_name,font_size,font_color,x_second_column,y_prop_array[7],2);
//---
   CreateLabel(0,0,pos_prop_names[8],"Volume :",anchor,corner,font_name,font_size,font_color,x_first_column,y_prop_array[8],2);
   CreateLabel(0,0,pos_prop_values[8],GetValInfoPanel(8),anchor,corner,font_name,font_size,font_color,x_second_column,y_prop_array[8],2);
//---
   CreateLabel(0,0,pos_prop_names[9],"Stop Loss :",anchor,corner,font_name,font_size,font_color,x_first_column,y_prop_array[9],2);
   CreateLabel(0,0,pos_prop_values[9],GetValInfoPanel(9),anchor,corner,font_name,font_size,font_color,x_second_column,y_prop_array[9],2);
//---
   CreateLabel(0,0,pos_prop_names[10],"Take Profit :",anchor,corner,font_name,font_size,font_color,x_first_column,y_prop_array[10],2);
   CreateLabel(0,0,pos_prop_values[10],GetValInfoPanel(10),anchor,corner,font_name,font_size,font_color,x_second_column,y_prop_array[10],2);
//---
   CreateLabel(0,0,pos_prop_names[11],"Time :",anchor,corner,font_name,font_size,font_color,x_first_column,y_prop_array[11],2);
   CreateLabel(0,0,pos_prop_values[11],GetValInfoPanel(11),anchor,corner,font_name,font_size,font_color,x_second_column,y_prop_array[11],2);
//---
   CreateLabel(0,0,pos_prop_names[12],"Identifier :",anchor,corner,font_name,font_size,font_color,x_first_column,y_prop_array[12],2);
   CreateLabel(0,0,pos_prop_values[12],GetValInfoPanel(12),anchor,corner,font_name,font_size,font_color,x_second_column,y_prop_array[12],2);
//---
   CreateLabel(0,0,pos_prop_names[13],"Type :",anchor,corner,font_name,font_size,font_color,x_first_column,y_prop_array[13],2);
   CreateLabel(0,0,pos_prop_values[13],GetValInfoPanel(13),anchor,corner,font_name,font_size,font_color,x_second_column,y_prop_array[13],2);
//---
   ChartRedraw(); // Redraw the chart
  }

SetInfoPanel() fonksiyonuna daha yakından bakalım. Grafik nesnelerinin özellikleriyle (koordinatlar, renk, yazı tipi, görüntülenen metin vb.) ilgili değişkenler fonksiyonun başında bildirilir. Bilgi panelindeki pozisyon özellikleri listesi için Y koordinatları dizisini doldurma işlemine dikkat edin. Bu işlem, yeni başlayanların anlayacağı şekilde uygulanmaktadır. Ancak bu, bir döngü kullanılırken birkaç satırlık koda indirgenebilir. Bunu aşağıdaki gibi yazabilirsiniz:

//--- Fill the array with coordinates for each line on the info panel
   for(int i=0; i<INFOPANEL_SIZE; i++)
     {
      if(i==0) y_prop_array[i]=y_property;
      else     y_prop_array[i]=y_property+line_height*i;
     }

Ardından, panelde görüntülenmesi gereken nesnelerin tüm özellikleri, daha önce oluşturulan CreateLabel() ve CreateEdit() fonksiyonlarının parametrelerinde tek seferde tek nesne ele alınarak belirtilmelidir. Tüm liste, bir döngü kullanılarak birkaç kod satırında da uygulanabilir. Bunun için, grafikte pozisyon özelliklerinin adlarının metnini görüntüleyen nesneler için başka bir dizi oluşturmamız gerekiyor. Bu sizin ev ödeviniz olsun.

Nesne sayısını elde eden GetPropertyValue() fonksiyonu, daha sonra dördüncü parametre (görüntülenen metin) olarak CreateLabel() fonksiyonuna aktarılan değeri döndürür. Bu, pozisyon özelliklerinin değerlerini gösterecek tüm nesneler ile ilgilidir. Fonksiyon tarafından döndürülen değer, nihai olarak panelde görüntülenecek olan ayarlanmış dize değeridir. Aşağıda, detaylı yorumlar içeren fonksiyon kodu yer almaktadır:

//+------------------------------------------------------------------+
//| RETURNING THE STRING WITH POSITION PROPERTY VALUE                |
//+------------------------------------------------------------------+
string GetPropertyValue(int number)
  {
//--- Sign indicating the lack of an open position or a certain property
//    E.g. the lack of a comment, Stop Loss or Take Profit
   string empty="-";
//--- If an open position exists, return the value of the requested property
   if(pos_open)
     {
      switch(number)
        {
         case 0  : return(pos_symbol);                                           break;
         case 1  : return(IntegerToString((int)pos_magic));                      break;
         //--- return the value of the comment, if any, otherwise return the sign indicating the lack of comment
         case 2  : return(pos_comment!="" ? pos_comment : empty);                break;
         case 3  : return(DoubleToString(pos_swap,2));                           break;
         case 4  : return(DoubleToString(pos_commission,2));                     break;
         case 5  : return(DoubleToString(pos_price,_Digits));                    break;
         case 6  : return(DoubleToString(pos_cprice,_Digits));                   break;
         case 7  : return(DoubleToString(pos_profit,2));                         break;
         case 8  : return(DoubleToString(pos_volume,2));                         break;
         case 9  : return(pos_sl!=0.0 ? DoubleToString(pos_sl,_Digits) : empty); break;
         case 10 : return(pos_tp!=0.0 ? DoubleToString(pos_tp,_Digits) : empty); break;
         case 11 : return(TimeToString(pos_time,TIME_DATE|TIME_MINUTES));        break;
         case 12 : return(IntegerToString((int)pos_id));                         break;
         case 13 : return(PositionTypeToString(pos_type));                       break;
         
         default : return(empty);
        }
     }
//---
// If there is no open position, return the sign indicating the lack of the open position "-"
   return(empty);
  }

Yukarıdaki kod, açık pozisyon olması koşuluyla fonksiyona aktarılan her bir sayı için belirli bir değerin hazırlandığını göstermektedir. Halihazırda açık pozisyon yoksa, fonksiyon, pozisyon özelliği değerleriyle ilgili tüm nesneler için görüntülenen bir tire (-) döndürür.

SetInfoPanel() fonksiyonunun sonunda, zorunlu bir grafik yeniden çizimi için tasarlanmış ChartRedraw() fonksiyonunu çağırırız. Bu fonksiyon çağrılmadıkça yapılan değişiklikleri göremezsiniz.

Şimdi Uzman Danışman tarafından oluşturulan tüm grafik nesnelerini silecek bir fonksiyon yazmamız gerekiyor. Buna DeleteInfoPanel() diyelim:

//+------------------------------------------------------------------+
//| DELETING THE INFO PANEL                                          |
//+------------------------------------------------------------------+
void DeleteInfoPanel()
  {
   DeleteObjectByName("InfoPanelBackground");   // Delete the panel background
   DeleteObjectByName("InfoPanelHeader");       // Delete the panel header
//--- Delete position properties and their values
   for(int i=0; i<INFOPANEL_SIZE; i++)
     {
      DeleteObjectByName(pos_prop_names[i]);    // Delete the property
      DeleteObjectByName(pos_prop_values[i]);   // Delete the value
     }
//---
   ChartRedraw(); // Redraw the chart
  }

Şimdi yalnızca oluşturduğumuz yöntemleri, MQL5 Sihirbazında oluşturduktan sonra orijinal olarak şablonda bulunan Uzman Danışmanın ana fonksiyonları arasında dağıtmamız gerekiyor. Bu en kolay kısım:

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Get the properties and set the panel
   GetPositionProperties();
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//--- Print the deinitialization reason to the journal
   Print(GetDeinitReasonText(reason));
//--- When deleting from the chart
   if(reason==REASON_REMOVE)
      //--- Delete all objects relating to the info panel from the chart
      DeleteInfoPanel();

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//--- Get the properties and update the values on the panel
   GetPositionProperties();

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

Karşınıza çıkabilecek tek şey, sonlandırma nedeni kodunun bir metin açıklamasını döndüren GetDeinitReasonText() fonksiyonudur:

//+---------------------------------------------------------------------+
//| RETURNING A TEXTUAL DESCRIPTION OF THE DEINITIALIZATION REASON CODE |
//+---------------------------------------------------------------------+
string GetDeinitReasonText(int reason_code)
  {
   string text="";
//---
   switch(reason_code)
     {
      case REASON_PROGRAM :     // 0
         text="The Expert Advisor has stopped working calling the ExpertRemove() function.";   break;
      case REASON_REMOVE :      // 1
         text="The '"+EXPERT_NAME+"' program has been removed from the chart.";                break;
      case REASON_RECOMPILE :   // 2
         text="The '"+EXPERT_NAME+"' program has been recompiled.";                            break;
      case REASON_CHARTCHANGE : // 3
         text="Chart symbol or period has been changed.";                                      break;
      case REASON_CHARTCLOSE :  // 4
         text="The chart is closed.";                                                          break;
      case REASON_PARAMETERS :  // 5
         text="Input parameters have been changed by the user.";                               break;
      case REASON_ACCOUNT :     // 6
         text="A different account has been activated.";                                       break;
      case REASON_TEMPLATE :    // 7
         text="A different chart template has been applied.";                                  break;
      case REASON_INITFAILED :  // 8
         text="A flag specifying that the OnInit() handler returned zero value.";              break;
      case REASON_CLOSE :       // 9
         text="The terminal has been closed.";                                                 break;
      default : text="The reason is undefined.";
     }
//---
   return text;
  }

Uzman Danışmanı şu anda açık pozisyonu olmayan grafik sembolünde kullanmaya çalışırsanız, panelde pozisyon özelliği değerleri yerine tireler göreceksiniz. Panel, bu pozisyon kapatıldıktan sonra aynı görünecektir.

Şekil 2. Bir açık pozisyon yokluğunda bilgi paneli.

Şekil 2. Bir açık pozisyon yokluğunda bilgi paneli.

Uzman Danışman açık pozisyonu olan sembol grafiğine eklenirse veya Uzman Danışman grafiğe eklendikten sonra bir pozisyon açılırsa, tüm tireler uygun pozisyon özellik değerleri ile değiştirilir:

Şekil 3. Açık pozisyon özelliklerini gösteren bilgi paneli.

Şekil 3. Açık pozisyon özelliklerini gösteren bilgi paneli.

Burada küçük bir özellik var. Paneldeki değerler, pozisyonu kapattıktan sonra yeni tike kadar güncellenmez. Değerleri anında güncellemenin bir yolu var, ancak bunu gerçekleştirmek için yapılması gerekenler serinin bir sonraki makalesinde ele alınacak.

 

Sonuç

Bu makalede tanıtılan fonksiyonlardan bazıları, MQL5 Tarif Defteri serisinin sonraki makalelerinde de kullanılacak, diğerleri ise elimizdeki işe göre değiştirilecek ve geliştirilecektir. Her yeni makale mantık olarak bir öncekinin devamı olduğu için makaleleri sırayla okumanız önerilir. Bu kesinlikle sizin yetkinlik ve beceri seviyenize de bağlıdır, bu nedenle daha yeni yayınlar ile başlamak daha mantıklı ve ilginç olabilir. 

Kaynak kod dosyası makaleye eklenmiştir.

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

Ekli dosyalar |
MQL5 Tarif Defteri Pozisyon Parametrelerini MetaTrader 5 Strateji Test Cihazında Analiz Etme MQL5 Tarif Defteri Pozisyon Parametrelerini MetaTrader 5 Strateji Test Cihazında Analiz Etme
"MQL5 Tarif Defteri: Özel Bilgi Panelindeki Pozisyon Özellikleri" adlı önceki makalesinden Uzman Danışmanın değiştirilmiş bir versiyonunu sunacağız. Ele alacağımız sorunlardan bazıları, çubuklardan veri alma, mevcut sembol üzerindeki yeni çubuk olaylarını kontrol etme, Standart Kitaplığın bir alım satım sınıfını bir dosyaya ekleme, alım satım sinyallerini aramak için bir fonksiyon ve alım satım işlemlerini yürütmek için bir fonksiyon oluşturmanın yanı sıra OnTrade() fonksiyonundaki alım satım olaylarını belirlemeyi içerir.
MQL5 Tarif Defteri Pozisyon Özelliklerini Elde Etme MQL5 Tarif Defteri Pozisyon Özelliklerini Elde Etme
Bu makalede, tüm pozisyon özelliklerini elde eden ve bunları kullanıcıya bir iletişim kutusunda gösteren bir betik oluşturacağız. Betiği çalıştırdıktan sonra, geçerli semboldeki pozisyon özelliklerini görüntülemek veya tüm simgelerdeki pozisyon özelliklerini görüntülemek için harici parametrelerdeki açılır listede bulunan iki moddan birini seçebileceksiniz.
MQL5 Tarif Defteri Alım Satım Seviyelerini Ayarlarken/Değiştirirken Hatalardan Nasıl Kaçınılır? MQL5 Tarif Defteri Alım Satım Seviyelerini Ayarlarken/Değiştirirken Hatalardan Nasıl Kaçınılır?
"MQL5 Tarif Defteri: MetaTrader 5 Strateji Test Cihazındaki Pozisyon Parametrelerini Analiz Etme" isimli serinin önceki makalesinden Uzman Danışman üzerindeki çalışmamızın devamında, bunu birçok faydalı fonksiyon ile geliştirecek ve mevcut olanları iyileştirip optimize edeceğiz. Uzman Danışman, bu sefer MetaTrader 5 Strateji Test Cihazında optimize edilebilecek harici parametrelere sahip olacak ve bazı yönlerden basit bir alım sistemine benzeyecektir.
MQL5 Tarif Defteri Farklı Yazdırma Modlarını Kullanma MQL5 Tarif Defteri Farklı Yazdırma Modlarını Kullanma
Bu, MQL5 Tarif Defteri serisinin ilk makalesidir. Programlamaya ilk adımlarını atanların yeni dile yavaş yavaş aşina olmaları için basit örneklerle başlayacağım. Hayatımdaki gördüğüm ilk programlama dili olduğunu düşünürsek, oldukça zorlandığımı söyleyebileceğim alım satım sistemlerini tasarlama ve programlama konusundaki ilk çabalarımı hatırlıyorum. Ancak, düşündüğümden daha kolay çıktı ve oldukça karmaşık bir program geliştirmem sadece birkaç ayımı aldı.