"Çalışma Sırasında" Kullanıcı Panelinden Uzman Danışman Parametrelerini Değiştirme

Anatoli Kazharski | 13 Ocak, 2022

İçindekiler

Giriş
1. Odaktaki Sorunlar
2. Uzman Danışmanın Yapısı
3. Kullanıcı Paneli ile Etkileşim
Sonuç


Giriş

Karmaşık Uzman Danışmanlar geliştirirken, harici parametrelerin sayısı çok fazla olabilir. Ayarların da sık sık manuel olarak değiştirilmesi gerekir, bu da büyük bir parametreler listesini düşündüğümüzde tüm süreci çok zaman alıcı hale getirir. Elbette, setleri önceden hazırlayıp kaydedebilirsiniz, ancak bazı durumlarda gereken bu olmayabilir. MQL5'in her zaman olduğu gibi kullanışlı olduğu yer burasıdır.

Alım satım yaparken bir Uzman Danışmanın parametrelerini "çalışma sırasında" değiştirmemizi sağlayacak bir kullanıcı paneli oluşturmaya çalışalım. Bu, manuel veya yarı otomatik modda alım satım yapanların dikkatini çekebilir. Herhangi bir değişiklik yapıldığında, parametreler daha sonra panelde daha fazla görüntülenmek üzere bir dosyaya yazılacak ve Uzman Danışman tarafından okunacaktır.


1. Odaktaki Sorunlar

Örnek olarak, JMA göstergesi yönünde bir pozisyon açan basit bir EA geliştireceğiz. Bu EA, mevcut sembol ve zaman aralığında tamamlanmış çubuklar üzerinde çalışacaktır. Harici parametreler Gösterge Dönemi, Zarar Durdur, Kâr Al, Ters ve Lotu içerecektir. Örneğimizde bu seçenekler gayet yeterli olacaktır.

Paneli açmak/kapatmak (Bilgi Panelini Aç/Kapat) ve Uzman Danışman parametre ayar modunu ("Çalışma Sırasında" Ayarı) etkinleştirmek/devre dışı bırakmak için iki parametre daha ekleyelim. Parametre sayısı fazla olduğunda, ek seçenekleri listenin en başına veya sonuna yerleştirmek kolay ve hızlı erişim için her zaman daha uygundur.

Şekil 1. Uzman Danışman parametrelerine sahip Bilgi Paneli

Şekil 1. Uzman Danışman parametrelerine sahip Bilgi Paneli

"Çalışma Sırasında" ayar modu varsayılan olarak devre dışıdır. Bu modu ilk kez etkinleştirdiğinizde, Uzman Danışman, o anda sahip olduğu tüm parametreleri kaydetmek için bir dosya oluşturur. Dosya yanlışlıkla silinirse de aynısı olur. Uzman Danışman, silme işlemini algılayacak ve dosyayı yeniden oluşturacaktır. "Çalışma Sırasında" ayar modu devre dışı bırakıldığında, Uzman Danışman harici parametreler ile yönlendirilecektir.

Bu mod etkinleştirilirse, Uzman Danışman dosyadaki parametreleri okuyacak ve gerekli değeri bilgi panelindeki herhangi bir parametreye tıklayarak seçebilecek veya açılan iletişim penceresinde yeni bir değer girebileceksiniz. Dosya verileri her yeni değer seçildiğinde güncellenecektir.


2. Uzman Danışmanın yapısı

Program küçük olmasına ve tüm fonksiyonlar tek bir dosyaya kolayca sığabilmesine rağmen, tüm proje bilgileri arasında gezinmek düzgün bir şekilde kategorize edildiğinde hala çok kolaydır. Bu nedenle, fonksiyonları türe göre kategorize etmek ve bunları ilk başta farklı dosyalarda tutarak daha sonra ana dosyaya eklemek en iyisidir. Aşağıdaki şekil, Çalışma Sırasında Uzman Danışman ile paylaşılan bir proje klasörünü ve tüm içerik dosyalarını göstermektedir. İçerik dosyaları ayrı bir klasöre (Include) yerleştirilir.

Şekil 2. MetaEditor'ın Navigatör penceresindeki proje dosyaları

Şekil 2. MetaEditor'ın Navigatör penceresindeki proje dosyaları

Kod, içerik dosyaları ana dosyayla aynı klasörde olduğunda, aşağıdaki gibidir:

//+------------------------------------------------------------------+
//| CUSTOM LIBRARIES                                                 |
//+------------------------------------------------------------------+
#include "Include/!OnChartEvent.mqh"
#include "Include/CREATE_PANEL.mqh"
#include "Include/FILE_OPERATIONS.mqh"
#include "Include/ERRORS.mqh"
#include "Include/ARRAYS.mqh"
#include "Include/TRADE_SIGNALS.mqh"
#include "Include/TRADE_FUNCTIONS.mqh"
#include "Include/GET_STRING.mqh"
#include "Include/GET_COLOR.mqh"
#include "Include/ADD_FUNCTIONS.mqh"

Dosyaların nasıl ekleneceğine dair daha fazla bilgi MQL5 Referansı bölümünde bulunabilir.

Global değişkenlere - harici parametrelerin kopyalarına - ihtiyacımız olacaktır. Bunların değerleri, Uzman Danışmanın moduna göre harici parametrelerden veya dosyadan atanacaktır. Bu değişkenler tüm program kodu boyunca kullanılır: örneğin değerlerin bilgi panelinde görüntülenmesinde, alım satın fonksiyonlarında vb.

// COPY OF EXTERNAL PARAMETERS
int    gPeriod_Ind = 0;
double gTakeProfit = 0.0;
double gStopLoss   = 0.0;
bool   gReverse    = false;
double gLot        = 0.0;

Diğer tüm Uzman Danışmanlarda olduğu gibi, ana fonksiyonlarımız olacak: OnInit, OnTick ve OnDeinit. Ayrıca OnTimer fonksiyonu olacak. Bu fonksiyon, parametre dosyasının varlığını her saniye kontrol edecek ve yanlışlıkla silinmesi durumunda bunu geri yükleyecektir. Kullanıcı paneli ile etkileşime geçmemiz gerektiği için, OnChartEvent fonksiyonu da kullanılacaktır. Bu fonksiyon, diğer ilgili fonksiyonlarla birlikte ayrı bir dosyaya (!OnChartEvent.mqh) yerleştirilmiştir.

Ana dosyanın çekirdek kodu aşağıdaki gibidir:

#define szArrIP 5 // Size of the parameter array
#define NAME_EXPERT MQL5InfoString(MQL5_PROGRAM_NAME) // Name of EA
#define TRM_DP TerminalInfoString(TERMINAL_DATA_PATH) // Folder that contains the terminal data
//+------------------------------------------------------------------+
//| STANDARD LIBRARIES                                               |
//+------------------------------------------------------------------+
#include <Trade/SymbolInfo.mqh>
#include <Trade/Trade.mqh>
//+------------------------------------------------------------------+
//| CUSTOM LIBRARIES                                                 |
//+------------------------------------------------------------------+
#include "Include/!OnChartEvent.mqh"
#include "Include/CREATE_PANEL.mqh"
#include "Include/FILE_OPERATIONS.mqh"
#include "Include/ERRORS.mqh"
#include "Include/ARRAYS.mqh"
#include "Include/TRADE_SIGNALS.mqh"
#include "Include/TRADE_FUNCTIONS.mqh"
#include "Include/GET_STRING.mqh"
#include "Include/GET_COLOR.mqh"
#include "Include/ADD_FUNCTIONS.mqh"
//+------------------------------------------------------------------+
//| CREATING CLASS INSTANCES                                         |
//+------------------------------------------------------------------+
CSymbolInfo mysymbol; // CSymbolInfo class object 
CTrade      mytrade;  // CTrade class object
//+------------------------------------------------------------------+
//| EXTERNAL PARAMETERS                                              |
//+------------------------------------------------------------------+
input int    Period_Ind      = 10;    // Indicator Period
input double TakeProfit      = 100;   // Take Profit (p)
input double StopLoss        = 30;    // Stop Loss (p)
input bool   Reverse         = false; // Reverse Position
input double Lot             = 0.1;   // Lot
//---
input string slash="";       // * * * * * * * * * * * * * * * * * * *
sinput bool  InfoPanel       = true;  // On/Off Info Panel
sinput bool  SettingOnTheFly = false; // "On The Fly" Setting
//+------------------------------------------------------------------+
//| GLOBAL VARIABLES                                                 |
//+------------------------------------------------------------------+
int hdlSI=INVALID_HANDLE; // Signal indicator handle
double lcheck=0;  // For the check of parameter values
bool isPos=false; // Position availability
//--- COPY OF EXTERNAL PARAMETERS
int    gPeriod_Ind = 0;
double gTakeProfit = 0.0;
double gStopLoss   = 0.0;
bool   gReverse    = false;
double gLot        = 0.0;
//+------------------------------------------------------------------+
//| EXPERT ADVISOR INITIALIZATION                                    |
//+------------------------------------------------------------------+
void OnInit()
  {
   if(NotTest()) { EventSetTimer(1); } // If it's not the tester, set the timer
//---
   Init_arr_vparams(); // Initialization of the array of parameter values
   SetParameters(); // Set the parameters
   GetIndicatorsHandles(); // Get indicator handles
   NewBar(); // New bar initialization
   SetInfoPanel(); // Info panel
  }
//+------------------------------------------------------------------+
//| CURRENT SYMBOL TICKS                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
// If the bar is not new, exit
   if(!NewBar()) { return; }
   else
     { TradingBlock(); }
  }
//+------------------------------------------------------------------+
//| TIMER                                                            |
//+------------------------------------------------------------------+
void OnTimer()
  {
   SetParameters(); SetInfoPanel();
  }
//+------------------------------------------------------------------+
//| EXPERT ADVISOR DEINITIALIZATION                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
// Get the deinitialization reason code
   if(NotTest()) {
     { Print(getUnitReasonText(reason)); }
//---
// When deleting from the chart
   if(reason==REASON_REMOVE)
     {
      // Delete all objects created by the Expert Advisor
      DeleteAllExpertObjects();
      //---
      if(NotTest()) { EventKillTimer(); } // Stop the timer
      IndicatorRelease(hdlSI); // Delete the indicator handle
     }
  }

Ayrıca ana dosyaya birkaç fonksiyon daha ekledim:

Bu fonksiyonlar için kaynak kodları makaleye ekli dosyalarda bulunabilir. Burada sadece SetParameters fonksiyonunu inceleyeceğiz (açıklayıcı yorumlar kodda verilmiştir):
//+------------------------------------------------------------------+
//| SETTING PARAMETERS IN TWO MODES                                  |
//+------------------------------------------------------------------+
// If this variable is set to false, the parameters in the file are read from the array
// where they are saved for quick access after they have been read for the first time.
// The variable is zeroed out upon the change in the value on the panel.
bool flgRead=false;
double arrParamIP[]; // Array where the parameters from the file are saved
//---
void SetParameters()
  {
// If currently in the tester or
// in real time but with the "On The Fly" Setting mode disabled
   if(!NotTest() || (NotTest() && !SettingOnTheFly))
     {
      // Zero out the variable and parameter array
      flgRead=false;
      ArrayResize(arrParamIP,0);
      //---
      // Check the Indicator Period for correctness
      if(Period_Ind<=0)
        { lcheck=10; }
      else { lcheck=Period_Ind; }
      gPeriod_Ind=(int)lcheck;
      //---
      gStopLoss=StopLoss;
      gTakeProfit=TakeProfit;
      gReverse=Reverse;
      //---
      // Check the Lot for correctness
      if(Lot<=0)
        { lcheck=0.1; }
      else { lcheck=Lot; }
      gLot=lcheck;
     }
   else // If "On The Fly" Setting mode is enabled
     {
      // Check whether there is a file to write/read parameters to/from the file
      string lpath="";
      //---
      // If the folder exists
      if((lpath=CheckCreateGetPath())!="")
        {
         // Write or read the file
         WriteReadParameters(lpath);
        }
     }
  }

SetParameters fonksiyonunun kaynak kodu basit ve anlaşılırdır. WriteReadParameters fonksiyonuna daha yakından bakalım. Burada her şey oldukça basit. İlk olarak parametreleri içeren dosyanın mevcut olup olmadığını kontrol ederiz. Varsa, dosyayı okuruz ve bir diziye GetValuesParamsFromFile fonksiyonunu kullanarak parametre değerlerini yazarız. Dosya yoksa, kendisine yazılan mevcut harici parametreler ile oluşturulacaktır.

Aşağıda, yukarıda açıklanan eylemlerin uygulanması için daha ayrıntılı yorumlar içeren kod yer almaktadır:

//+------------------------------------------------------------------+
//| WRITE DATA TO FILE                                               |
//+------------------------------------------------------------------+
void WriteReadParameters(string pth)
  {
   string nm_fl=pth+"ParametersOnTheFly.ini"; // File name and path
//---
// Get the file handle to read the file
   int hFl=FileOpen(nm_fl,FILE_READ|FILE_ANSI);
//---
   if(hFl!=INVALID_HANDLE) // If the handle has been obtained, the file exists
     {
      // Get parameters from the file
      if(!flgRead)
        {
         // Set the array size
         ArrayResize(arrParamIP,szArrIP);
         //---
         // Fill the array with values from the file
         flgRead=GetValuesParamsFromFile(hFl,arrParamIP);
        }
      //---
      // If the array size is correct,...
      if(ArraySize(arrParamIP)==szArrIP)
        {
         // ...set the parameters to the variables
         //---
         // Check the Indicator Period for correctness
         if((int)arrParamIP[0]<=0) { lcheck=10; }
         else { lcheck=(int)arrParamIP[0]; }
         gPeriod_Ind=(int)lcheck;
         //---
         gTakeProfit=arrParamIP[1];
         gStopLoss=arrParamIP[2];
         gReverse=arrParamIP[3];
         //---
         // Check the Lot for correctness
         if(arrParamIP[4]<=0)
           { lcheck=0.1; }
         else { lcheck=arrParamIP[4]; }
         gLot=lcheck;
        }
     }
   else // If the file does not exist
     {
      iZeroMemory(); // Zero out variables
      //---
      // When creating the file, write current parameters of the Expert Advisor
      //---
      // Get the file handle to write to the file
      int hFl2=FileOpen(nm_fl,FILE_WRITE|FILE_CSV|FILE_ANSI,"");
      //---
      if(hFl2!=INVALID_HANDLE) // If the handle has been obtained
        {
         string sep="=";
         //---
         // Parameter names and values are obtained from arrays in the ARRAYS.mqh file
         for(int i=0; i<szArrIP; i++)
           { FileWrite(hFl2,arr_nmparams[i],sep,arr_vparams[i]); }
         //---
         FileClose(hFl2); // Close the file
         //---
         Print("File with parameters of the "+NAME_EXPERT+" Expert Advisor created successfully.");
        }
     }
//---
   FileClose(hFl); // Close the file
  }

WriteReadParameters ve GetValuesParamsFromFile fonksiyonları FILE_OPERATIONS.mqh dosyasında bulunabilir.

Fonksiyonlardan bazıları, "Diğer Uygulamalar için MetaTrader 5 Kotasyonları Nasıl Hazırlanır?" başlıklı önceki makalemde zaten anlatılmıştır, bu yüzden burada bunların üzerinde durmayacağız. Çok anlaşılır olmalarından ve kapsamlı bir şekilde yorumlanmalarından dolayı alım satım fonksiyonlarına dair herhangi bir zorluk yaşamamanız lazım. Burada makalenin ana konusuna odaklanacağız.


3. Kullanıcı Paneli ile Etkileşim

!OnChartEvent.mqh dosyası, kullanıcı paneliyle etkileşime yönelik fonksiyonlar içerir. Birçok fonksiyonda kullanılan değişkenler ve diziler, ilk başta global kapsamda bildirilir:

// Current value on the panel or
// entered in the input box
string currVal="";
bool flgDialogWin=false; // Flag for panel existence
int
szArrList=0,// Size of the option list array
number=-1; // Parameter number in the panel list
string
nmMsgBx="",  // Name of the dialog window
nmValObj=""; // Name of the selected object
//---
// Option list arrays in the dialog window
string lenum[],lenmObj[];
//---
// colors of the dialog window elements
color
clrBrdBtn=clrWhite,
clrBrdFonMsg=clrDimGray,clrFonMsg=C'15,15,15',
clrChoice=clrWhiteSmoke,clrHdrBtn=clrBlack,
clrFonHdrBtn=clrGainsboro,clrFonStr=C'22,39,38';

Bundan sonra olayları işleyen ana fonksiyon gelir. Örneğimizde, iki olayı ele almamız gerekiyor:

Diğer MQL5 olaylarına dair daha fazla bilgiyi MQL5 Referansı içinde okuyabilirsiniz.

İlk olarak, "Çalışma Sırasında" ayar modunun etkin olması (SettingOnTheFly) koşuluyla, olayları yalnızca gerçek zamanlı olarak işlemek için bir kontrol ayarlayalım. Olayların işlenmesi ayrı fonksiyonlar ile ele alınacaktır: ChartEvent_ObjectClick ve ChartEvent_ObjectEndEdit.

//+------------------------------------------------------------------+
//| USER EVENTS                                                      |
//+------------------------------------------------------------------+
void OnChartEvent(const int     id,
                  const long   &lparam,
                  const double &dparam,
                  const string &sparam)
  {
// If the event is real time and the "On The Fly" setting mode is enabled
   if(NotTest() && SettingOnTheFly)
     {
      //+------------------------------------------------------------------+
      //| THE CHARTEVENT_OBJECT_CLICK EVENT                                |
      //+------------------------------------------------------------------+
      if(ChartEvent_ObjectClick(id,lparam,dparam,sparam)) { return; }
      //---
      //+------------------------------------------------------------------+
      //| THE CHARTEVENT_OBJECT_ENDEDIT EVENT                              |
      //+------------------------------------------------------------------+
      if(ChartEvent_ObjectEndEdit(id,lparam,dparam,sparam)) { return; }
     }
//---
   return;
  }

Listedeki nesneye tıkladığınızda, bilgi paneli üzerinde, başka bir değer seçmenizi veya giriş kutusuna yeni bir değer girmenize olanak sağlayan bir iletişim penceresi görünecektir.

Şekil 3. Seçilen parametre değerinde değişiklik için iletişim penceresi

Şekil 3. Seçilen parametre değerinde değişiklik için iletişim penceresi

Bunun nasıl çalıştığına daha yakından bakalım. Program, bir grafik nesnesine tıklandığında, bir grafik nesnesine gerçekten bir tıklama olup olmadığını olay tanımlayıcısı ile kontrol etmek için ilk olarak ChartEvent_ObjectClick fonksiyonunu kullanır.

İletişim penceresinin grafiğin ortasında açılmasını istiyorsanız, grafik boyutunu bilmeniz gerekir. Bu, ChartGetInteger fonksiyonunda CHART_WIDTH_IN_PIXELS ve CHART_HEIGHT_IN_PIXELS özelliklerinin belirtilmesi ile yapılabilir. Daha sonra program DialogWindowInfoPanel'e geçer. MQL5 Referansı bölümünde tüm grafik özelliklerine aşinalık kazanabilirsiniz.

Aşağıda, yukarıdaki eylemlerin uygulanmasına yönelik kod yer almaktadır:

//+------------------------------------------------------------------+
//| THE CHARTEVENT_OBJECT_CLICK EVENT                                |
//+------------------------------------------------------------------+
bool ChartEvent_ObjectClick(int id,long lparam,double dparam,string sparam)
  {
   // If there was an event of clicking on a graphical object
   if(id==CHARTEVENT_OBJECT_CLICK) // id==1
     {
      Get_STV(); // Get all data on the symbol
      //---
      string clickedChartObject=sparam; // Name of the clicked object
      //---
      // Get the chart size
      width_chart=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,0);
      height_chart=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,0);
      //---
      DialogWindowInfoPanel(clickedChartObject);
     }
//---
   return(false);
  }

İlk olarak iletişim penceresinin o anda açık olup olmadığını DialogWindowInfoPanel fonksiyonunu kullanarak kontrol ederiz. Pencere bulunamazsa, GetNumberClickedObjIP fonksiyonu, tıklamanın bilgi panelindeki listeden bir nesneyle ilişkili olup olmadığını kontrol eder. Tıklanan nesne listeden bir nesneyse, fonksiyon nesneler dizisinden ilgili öğe sayısını döndürür. InitArraysAndDefault fonksiyonu, bu sayıyı kullanarak iletişim penceresindeki liste dizi boyutunu ve varsayılan değerleri belirler. Tüm eylemler başarılıysa iletişim penceresi görünür.

DialogWindowInfoPanel fonksiyonu iletişim penceresinin zaten açık olduğunu belirlerse, program, iletişim penceresinde bir nesneye tıklama olup olmadığını kontrol eder. Örneğin iletişim penceresi açıldığında panelde o anda değeri görüntülenen satır seçili görünecektir. Listedeki başka bir seçeneğe tıklarsanız, program tıklanan iletişim penceresi listesi seçeneğini seçen SelectionOptionInDialogWindow fonksiyonunu kullanacaktır.

Zaten seçili olan liste seçeneğine tıklarsanız, bu nesne düzenlenecek bir nesne olarak tanımlanacaktır, böylece kutuya tıkladığınızda yeni bir değer girilebilmesi için bir giriş kutusu görünecektir. SetEditObjInDialogWindow fonksiyonu, giriş kutusunun ayarlanmasından sorumludur.

Son olarak Apply (Uygula) butonuna tıklandığında program değerin değiştirilip değiştirilmediğini kontrol edecektir. Değiştirilmişse, panelde yeni değer görünecek ve dosyaya yazılacaktır.

İletişim penceresinin ana fonksiyonunun kodu aşağıda yer almaktadır:

//+------------------------------------------------------------------+
//| DIALOG WINDOW OF THE INFO PANEL                                  |
//+------------------------------------------------------------------+
void DialogWindowInfoPanel(string clickObj)
  {
// If there is currently no dialog window
   if(!flgDialogWin)
     {
      // Get the object number in the array
      // Exit if none of the parameters displayed on the panel has been clicked
      if((number=GetNumberClickedObjIP(clickObj))==-1) { return; }
      //---
      // Initialization of default values
      //and determination of the list array size
      if(!InitArraysAndDefault()) { return; }
      //---
      // Set the dialog window
      SetDialogWindow();
      //---
      flgDialogWin=true; // Mark the dialog window as open
      ChartRedraw();
     }
   else // If the dialog window is open
     {
      // Set the input box for the modification of the value
      SetEditObjInDialogWindow(clickObj);
      //---
      // If one of the buttons in the dialog box is clicked
      if(clickObj=="btnApply" || clickObj=="btnCancel")
        {
         // If the Apply button is clicked
         if(clickObj=="btnApply")
           {
            // Compare values on the panel with the ones on the list
            // If the value on the list is different from the one that is currently displayed on the panel 
            // (which means it is different from the one in the file),
            // ...change the value on the panel and update the file
            if(currVal!=ObjectGetString(0,nmValObj,OBJPROP_TEXT))
              {
               // Update the value on the panel
               ObjectSetString(0,nmValObj,OBJPROP_TEXT,currVal); ChartRedraw();
               //---
               // Read all data on the panel and write it to the file
               WriteNewData();
              }
           }
         //---
         DelDialogWindow(lenmObj); // Delete the dialog window
         iZeroMemory(); // Zero out the variables
         //---
         // Update the data
         SetParameters();
         GetHandlesIndicators();
         SetInfoPanel();
         //---
         ChartRedraw();
        }
      else // If neither Apply nor Cancel has been clicked
        {
         // Selection of the dialog window list option
         SelectionOptionInDialogWindow(clickObj);
         //---
         ChartRedraw();
        }
     }
  }

Giriş kutusuna her yeni bir değer girildiğinde, CHARTEVENT_OBJECT_EDIT olayı oluşturulur ve program ChartEvent_ObjectEndEdit fonksiyonuna geçer. İletişim penceresindeki değer değiştirilmişse, girilen değer saklanacak, bunun doğruluğu kontrol edilecek ve bu değer listedeki nesneye atanacaktır. Bunu aşağıdaki kodda daha ayrıntılı olarak görebilirsiniz:

//+------------------------------------------------------------------+
//| THE CHARTEVENT_OBJECT_ENDEDIT EVENT                              |
//+------------------------------------------------------------------+
bool ChartEvent_ObjectEndEdit(int id,long lparam,double dparam,string sparam)
  {
   if(id==CHARTEVENT_OBJECT_ENDEDIT) // id==3
     {
      string editObject=sparam; // Name of the edited object
      //---
      // If the value has been entered in the input box in the dialog window
      if(editObject=="editValIP")
        {
         // Get the entered value
         currVal=ObjectGetString(0,"editValIP",OBJPROP_TEXT);
         //---
         // (0) Period Indicator
         if(number==0)
           {
            // Correct the value if it is wrong
            if(currVal=="0" || currVal=="" || SD(currVal)<=0) { currVal="1"; }
            //---
            // Set the entered value
            ObjectSetString(0,"enumMB0",OBJPROP_TEXT,currVal);
           }
         //---
         // (4) Lot
         if(number==4)
           {
            // Correct the value if it is wrong
            if(currVal=="0" || currVal=="" || SD(currVal)<=0) { currVal=DS(SS.vol_min,2); }
            //---
            // Set the entered value
            ObjectSetString(0,"enumMB0",OBJPROP_TEXT,DS2(SD(currVal)));
           }
         //---
         // (1) Take Profit (p)
         // (2) Stop Loss (p)
         if(number==1 || number==2)
           {
            // Correct the value if it is wrong
            if(currVal=="0" || currVal=="" || SD(currVal)<=0) { currVal="1"; }
            //---
            // Set the entered value
            ObjectSetString(0,"enumMB1",OBJPROP_TEXT,currVal);
           }
         //---         
         DelObjbyName("editValIP"); ChartRedraw();
        }
     }
//---
   return(false);
  }

Çalışma halindeki Uzman Danışman aşağıdaki videoda görülebilir:



Sonuç

Makalenin sonuna eklenen sıkıştırılmış dosyalar daha detaylı inceleme için indirilebilir.

Umarım bu makale, MQL5 öğrenmeye yeni başlayanların, verilen basit örnekleri kullanarak birçok soruya hızlı yanıt bulmalarına yardımcı olacaktır. Sağlanan kod parçacıklarındaki bazı kontrolleri kasıtlı olarak dahil etmedim.

Örneğin, grafiğin yüksekliğini/genişliğini iletişim penceresi açıkken değiştirirseniz, iletişim penceresi otomatik olarak ortalanmayacaktır. Bunu listeden başka bir seçenek seçerek tamamlarsanız, ilgili satırı seçmeye yarayan nesne önemli ölçüde kaydırılacaktır. Bu sizin ev ödeviniz olsun. Programlama pratiği yapmak çok önemlidir ve ne kadar çok pratik yaparsanız o kadar iyi olursunuz.

İyi şanslar!