English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
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

MetaTrader 5Örnekler | 13 Ocak 2022, 09:30
49 0
Anatoli Kazharski
Anatoli Kazharski

Giriş

Bu makalede, aşağıda yer alan bir önceki makalede oluşturulan Uzman Danışmanı değiştireceğiz: "MQL5 Tarif Defteri: Özel Bilgi Panelindeki Pozisyon Özellikleri" ve aşağıdaki sorunları ele alacağız:

  • Mevcut sembol üzerindeki yeni çubuk olaylarını kontrol etme;
  • Çubuklardan veri alma;
  • 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 oluşturma;
  • Alım satım işlemlerini yürütmek için bir fonksiyon oluşturma;
  • OnTrade() fonksiyonundaki alım satım olaylarını belirleme.

Aslında, yukarıdaki konuların her biri kendi başına bir makaleyi hak edebilir, ancak bence böyle bir yaklaşım dilin incelenmesini yalnızca karmaşıklaştıracaktır.

Bu özelliklerin nasıl uygulanabileceğini size göstermek için çok basit örnekler kullanacağım. Diğer bir deyişle, yukarıda listelenen görevlerin her birinin uygulanması, deyim yerindeyse basit ve anlaşılır bir fonksiyona sığacaktır. Serinin gelecekteki makalelerinde belirli bir fikir geliştirirken, bu fonksiyonları, gerektiği kadar ve elimizdeki işin gerektirdiği ölçüde yavaş yavaş daha karmaşık hale getireceğiz.

İlk olarak, tüm fonksiyonlarına ihtiyaç duyacağımız için önceki makalesinden Uzman Danışmanı kopyalayalım.


Bir Uzman Danışman Geliştirme

Standart Kitaplıktan CTrade sınıfını dosyamıza ekleyerek başlayacağız. Bu sınıfta, alım satım işlemlerini yürütmek için gerekli tüm fonksiyonlar vardır. Başlangıç ​​olarak, bunları içeriğine bile bakmadan kolayca kullanabiliriz, işte yapacağımız şey bu.

Sınıfı eklemek için aşağıdakileri yazmamız gerekiyor:

//--- Include a class of the Standard Library
#include <Trade/Trade.mqh>

Daha sonra kolayca bulabilmek için bu kodu dosyanın en başına, örneğin #define direktifinden sonra yerleştirebilirsiniz. #include komutu, Trade.mqh dosyasının, <MetaTrader 5 terminal dizini>\MQL5\Include\Trade\ konumundan alınması gerektiğini belirtir. Aynı yaklaşım, fonksiyon içeren başka herhangi bir dosyayı eklemek için de kullanılabilir. Bu, özellikle proje kodunun miktarı artığında ve içinde gezinmenin zorlaştığı durumlarda kullanışlıdır.

Şimdi, tüm fonksiyonlarına erişebilmek için sınıfın bir örneğini oluşturmamız gerekiyor. Bu, sınıfın adından sonra örneğin adı yazılarak yapılabilir:

//--- Load the class
CTrade trade;

Uzman Danışmanın bu sürümünde, CTrade sınıfında bulunan tüm fonksiyonlardan yalnızca bir alım satım fonksiyonunu kullanacağız. Bu, bir pozisyon açmak için kullanılan PositionOpen() fonksiyonudur. Mevcut bir açık pozisyonun ters çevrilmesi için de kullanılabilir. Bu fonksiyonun sınıftan nasıl çağrılabileceği bu makalenin ilerleyen kısımlarında alım satım işlemlerinin yürütülmesinden sorumlu bir fonksiyon oluşturulurken gösterilecektir.

Ayrıca, global kapsamda iki dinamik dizi ekleriz. Bu diziler çubuk değerlerini alacaktır.

//--- Price data arrays
double               close_price[]; // Close (closing prices of the bar)
double               open_price[];  // Open (opening prices of the bar)

Ardından, alım satım işlemleri yalnızca tamamlanmış çubuklarda yürütüleceğinden, programın yeni çubuk olaylarını kontrol edeceği bir CheckNewBar() fonksiyonu oluşturun.

Aşağıda, detaylı yorumlar ile CheckNewBar() fonksiyon kodu yer almaktadır:

//+------------------------------------------------------------------+
//| CHECKING FOR THE NEW BAR                                         |
//+------------------------------------------------------------------+
bool CheckNewBar()
  {
//--- Variable for storing the opening time of the current bar
   static datetime new_bar=NULL;
//--- Array for getting the opening time of the current bar
   static datetime time_last_bar[1]={0};
//--- Get the opening time of the current bar
//    If an error occurred when getting the time, print the relevant message
   if(CopyTime(_Symbol,Period(),0,1,time_last_bar)==-1)
     { Print(__FUNCTION__,": Error copying the opening time of the bar: "+IntegerToString(GetLastError())+""); }
//--- If this is a first function call
   if(new_bar==NULL)
     {
      // Set the time
      new_bar=time_last_bar[0];
      Print(__FUNCTION__,": Initialization ["+_Symbol+"][TF: "+TimeframeToString(Period())+"]["
            +TimeToString(time_last_bar[0],TIME_DATE|TIME_MINUTES|TIME_SECONDS)+"]");
      return(false); // Return false and exit 
     }
//--- If the time is different
   if(new_bar!=time_last_bar[0])
     {
      new_bar=time_last_bar[0]; // Set the time and exit 
      return(true); // Store the time and return true
     }
//--- If we have reached this line, then the bar is not new, return false
   return(false);
  }

Yukarıdaki kodda görebileceğiniz gibi, CheckNewBar() fonksiyonu, çubuk yeniyse true veya henüz yeni bir çubuk yoksa false döndürür. Bu şekilde, alım satım/test yaparken durumu kontrol ederek sadece tamamlanmış çubuklarda alım satım işlemlerini yürütürsünüz.

Fonksiyonun en başında, bir static değişken ve datetime türünde bir statik dizi bildiririz. Statik yerel değişkenler, fonksiyondan çıkıldıktan sonra bile değerlerini korur. Bu yerel değişkenler, sonraki her fonksiyon çağrısında, fonksiyonun önceki çağrısında aldıkları değerleri içerecektir.

Ayrıca, lütfen CopyTime() fonksiyonuna dikkat edin. Bu, time_last_bar dizisindeki son çubuğun zamanını almamıza yardımcı olur. MQL5 Referansı içindeki fonksiyon sözdizimini kontrol ettiğinizden emin olun.

Ayrıca, bu makale dizisinde daha önce hiç bahsedilmeyen kullanıcı tanımlı TimeframeToString() fonksiyonu da fark edilebilir. Bu, zaman aralığı değerlerini kullanıcı için anlaşılır bir dizeye dönüştürür:

string TimeframeToString(ENUM_TIMEFRAMES timeframe)
  {
   string str="";
   //--- If the passed value is incorrect, take the time frame of the current chart
   if(timeframe==WRONG_VALUE || timeframe == NULL)
      timeframe = Period();
   switch(timeframe)
     {
      case PERIOD_M1  : str="M1";  break;
      case PERIOD_M2  : str="M2";  break;
      case PERIOD_M3  : str="M3";  break;
      case PERIOD_M4  : str="M4";  break;
      case PERIOD_M5  : str="M5";  break;
      case PERIOD_M6  : str="M6";  break;
      case PERIOD_M10 : str="M10"; break;
      case PERIOD_M12 : str="M12"; break;
      case PERIOD_M15 : str="M15"; break;
      case PERIOD_M20 : str="M20"; break;
      case PERIOD_M30 : str="M30"; break;
      case PERIOD_H1  : str="H1";  break;
      case PERIOD_H2  : str="H2";  break;
      case PERIOD_H3  : str="H3";  break;
      case PERIOD_H4  : str="H4";  break;
      case PERIOD_H6  : str="H6";  break;
      case PERIOD_H8  : str="H8";  break;
      case PERIOD_H12 : str="H12"; break;
      case PERIOD_D1  : str="D1";  break;
      case PERIOD_W1  : str="W1";  break;
      case PERIOD_MN1 : str="MN1"; break;
     }
//---
   return(str);
  }

CheckNewBar() fonksiyonunun nasıl kullanıldığı, diğer tüm gerekli fonksiyonlar hazır olduğunda makalenin ilerleyen bölümlerinde gösterilecektir. Şimdi istenen sayıda çubuğun değerlerini alan GetBarsData() fonksiyonuna bakalım.

//+------------------------------------------------------------------+
//| GETTING BAR VALUES                                               |
//+------------------------------------------------------------------+
void GetBarsData()
  {
//--- Number of bars for getting their data in an array
   int amount=2;
//--- Reverse the time series ... 3 2 1 0
   ArraySetAsSeries(close_price,true);
   ArraySetAsSeries(open_price,true);
//--- Get the closing price of the bar
//    If the number of the obtained values is less than requested, print the relevant message
   if(CopyClose(_Symbol,Period(),0,amount,close_price)<amount)
     {
      Print("Failed to copy the values ("
            +_Symbol+", "+TimeframeToString(Period())+") to the Close price array! "
            "Error "+IntegerToString(GetLastError())+": "+ErrorDescription(GetLastError()));
     }
//--- Get the opening price of the bar
//    If the number of the obtained values is less than requested, print the relevant message
   if(CopyOpen(_Symbol,Period(),0,amount,open_price)<amount)
     {
      Print("Failed to copy the values ("
            +_Symbol+", "+TimeframeToString(Period())+") to the Open price array! "
            "Error "+IntegerToString(GetLastError())+": "+ErrorDescription(GetLastError()));
     }
  }

Yukarıdaki kodu daha yakından inceleyelim. İlk olarak miktar (amount) değişkeninde verisini almamız gereken çubuk sayısını belirtiriz. Ardından, ArraySetAsSeries() fonksiyonunu kullanarak son (mevcut) çubuğun değeri dizinin sıfır indisinde olacak şekilde dizi indisleme sırasını ayarlarız. Örneğin, hesaplamalarınızda son çubuğun değerini kullanmak istiyorsanız, açılış fiyatı ile örneklendirilirse şu şekilde yazılabilir: open_price[0]. Sondan ikinci çubuğun gösterimi benzer şekilde olacaktır: open_price[1].

Kapanış ve açılış fiyatlarını alma mekanizması, son çubuğun zamanını elde etmemiz gereken CheckNewBar() fonksiyonuna benzerdir. Sadece bu durumda CopyClose() veCopyOpen() fonksiyonlarını kullanırız. Benzer şekilde, CopyHigh() ve CopyLow(), sırasıyla yüksek ve düşük çubuk fiyatlarını elde etmek için kullanılır.

Devam edelim ve bir pozisyonun açılması/ters çevrilmesi için sinyallerin nasıl belirleneceğini gösteren çok basit bir örneği ele alalım. Fiyat dizileri, iki çubuk için verileri saklar (mevcut çubuk ve önceki tamamlanmış çubuk). Tamamlanmış çubuktaki verileri kullanacağız.

  • Kapanış fiyatı açılış fiyatının üzerinde olduğunda, bir Alış sinyali yukarı yönlü çubuk) meydana gelir;
  • Kapanış fiyatı açılış fiyatının altında olduğunda, bir Satış sinyali (aşağı yönlü çubuk) olduğunda meydana gelir;

Bu basit koşulların uygulanması için kod aşağıda verilmektedir:

//+------------------------------------------------------------------+
//| DETERMINING TRADING SIGNALS                                      |
//+------------------------------------------------------------------+
int GetTradingSignal()
  {
//--- A Buy signal (0) :
   if(close_price[1]>open_price[1])
      return(0);
//--- A Sell signal (1) :
   if(close_price[1]<open_price[1])
      return(1);
//--- No signal (3):
   return(3);
  }

Gördüğünüz gibi, çok basit. Daha karmaşık durumların nasıl benzer bir şekilde ele alınacağı kolaylıkla anlaşılabilir. Fonksiyon, tamamlanmış bir çubuk yukarıdaysa sıfır veya tamamlanmış bir çubuk aşağıdaysa bir döndürür. Herhangi bir sebeple sinyal yoksa, fonksiyon 3 döndürecektir.

Şimdi, alım satım faaliyetlerinin uygulanması için bir TradingBlock() fonksiyonu oluşturmamız gerekiyor. Aşağıda, detaylı yorumlar içeren fonksiyon kodu yer almaktadır:

//+------------------------------------------------------------------+
//| TRADING BLOCK                                                    |
//+------------------------------------------------------------------+
void TradingBlock()
  {
   int               signal=-1;           // Variable for getting a signal
   string            comment="hello :)";  // Position comment
   double            start_lot=0.1;       // Initial volume of a position
   double            lot=0.0;             // Volume for position calculation in case of reverse position
   double            ask=0.0;             // Ask price
   double            bid=0.0;             // Bid price
//--- Get a signal
   signal=GetTradingSignal();
//--- Find out if there is a position
   pos_open=PositionSelect(_Symbol);
//--- If it is a Buy signal
   if(signal==0)
     {
      //--- Get the Ask price
      ask=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_ASK),_Digits);
      //--- If there is no position
      if(!pos_open)
        {
         //--- Open a position. If the position failed to open, print the relevant message
         if(!trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,start_lot,ask,0,0,comment))
           { Print("Error opening a BUY position: ",GetLastError()," - ",ErrorDescription(GetLastError())); }
        }
      //--- If there is a position
      else
        {
         //--- Get the position type
         pos_type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
         //--- If it is a SELL position
         if(pos_type==POSITION_TYPE_SELL)
           {
            //--- Get the position volume
            pos_volume=PositionGetDouble(POSITION_VOLUME);
            //--- Adjust the volume
            lot=NormalizeDouble(pos_volume+start_lot,2);
            //--- Open a position. If the position failed to open, print the relevant message
            if(!trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,lot,ask,0,0,comment))
              { Print("Error opening a SELL position: ",GetLastError()," - ",ErrorDescription(GetLastError())); }
           }
        }
      //---
      return;
     }
//--- If there is a Sell signal
   if(signal==1)
     {
      //-- Get the Bid price
      bid=NormalizeDouble(SymbolInfoDouble(_Symbol,SYMBOL_BID),_Digits);
      //--- If there is no position
      if(!pos_open)
        {
         //--- Open a position. If the position failed to open, print the relevant message
         if(!trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,start_lot,bid,0,0,comment))
           { Print("Error opening a SELL position: ",GetLastError()," - ",ErrorDescription(GetLastError())); }
        }
      //--- If there is a position
      else
        {
         //--- Get the position type
         pos_type=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
         //--- If it is a BUY position
         if(pos_type==POSITION_TYPE_BUY)
           {
            //--- Get the position volume
            pos_volume=PositionGetDouble(POSITION_VOLUME);
            //--- Adjust the volume
            lot=NormalizeDouble(pos_volume+start_lot,2);
            //--- Open a position. If the position failed to open, print the relevant message
            if(!trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,lot,bid,0,0,comment))
              { Print("Error opening a SELL position: ",GetLastError()," - ",ErrorDescription(GetLastError())); }
           }
        }
      //---
      return;
     }
  }

Bir pozisyon açılana kadar her şeyin anlaşılır olduğuna inanıyorum. Yukarıdaki kodda görebileceğiniz gibi, (trade (alım satım)) işaretçisini bir nokta takip eder ve ardından PositionOpen() yöntemi gelir. Bir sınıftan belirli bir yöntemi bu şekilde çağırabilirsiniz. Bir nokta koyduktan sonra, tüm sınıf yöntemlerini içeren bir liste göreceksiniz. Tek ihtiyacınız olan listeden gerekli yöntemi seçmek:

Şekil 1. Bir sınıf yönteminin çağrılması.

Şekil 1. Bir sınıf yöntemini çağırma.

TradingBlock() fonksiyonunda iki ana blok vardır - alış yapmak ve satış yapmak. Sinyalin yönünü belirledikten hemen sonra, Alış sinyali olması durumunda satış (ask) fiyatını, Satış sinyali olması durumunda ise alış (bid) fiyatını elde ederiz.

Alım satım emirlerinde kullanılan tüm fiyatlar/seviyeler, NormalizeDouble() fonksiyonu kullanılarak normalleştirilmelidir, aksi takdirde pozisyonu açma veya değiştirme girişimi hataya yol açar. Lot hesaplanırken de bu fonksiyonun kullanılması tavsiye edilir. Ayrıca, Zarar Durdur ve Kâr Al parametrelerinin sıfır değerinde olduklarını lütfen unutmayın. Alım satım seviyelerinin ayarlanmasına dair daha fazla bilgi, serinin bir sonraki makalesinde sağlanacaktır.

Artık tüm kullanıcı tanımlı fonksiyonlar hazır olduğuna göre, bunları doğru sırada düzenleyebiliriz:

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- Initialize the new bar
   CheckNewBar();
//--- Get position properties and update the values on 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()
  {
//--- If the bar is not new, exit
   if(!CheckNewBar())
      return;
//--- If there is a new bar
   else
     {
      GetBarsData();  // Get bar data
      TradingBlock(); // Check the conditions and trade
     }
//--- Get the properties and update the values on the panel
   GetPositionProperties();
  }

Değerlendirilecek tek bir şey kaldı: OnTrade() fonksiyonunu kullanarak alım satım olaylarını belirleme. Size genel bir fikir vermesi açısından burada bu konuya kısaca değineceğiz. Bizim durumumuzda aşağıdaki senaryoyu uygulamamız gerekiyor: bir pozisyonu manuel olarak açarken/kapatırken/değiştirirken, bilgi panelindeki pozisyon özellikleri listesindeki değerlerin yeni bir tik alındıktan sonra değil, işlem tamamlanır tamamlanmaz güncellenmesi gerekiyor. Bunun için sadece aşağıdaki kodu eklememiz gerekiyor:

//+------------------------------------------------------------------+
//| TRADE EVENT                                                      |
//+------------------------------------------------------------------+
void OnTrade()
  {
//--- Get position properties and update the values on the panel
   GetPositionProperties();
  }

Temel olarak, her şey hazır ve teste geçebiliriz. Strateji Test Cihazı, görselleştirme modunda bir test yapmanızı ve varsa hataları bulmanızı sağlar. Strateji Test Cihazının kullanımı, piyasaların kapalı olduğu hafta sonlarında bile programınızı geliştirmeye devam edebilmeniz nedeniyle faydalı görülebilir.

Strateji Test Cihazını kurun, görselleştirme modunu etkinleştirin ve Başlat seçeneğine tıklayın. Uzman Danışman, Strateji Test Cihazında alım satım yapmaya başlayacak ve aşağıda gösterilene benzer bir resim ortaya çıkacaktır:

Şekil 2. MetaTrader 5 Strateji Test Cihazında Görselleştirme modu.

Şekil 2. MetaTrader 5 Strateji Test Cihazındaki görselleştirme modu.

Görselleştirme modunda testi herhangi bir zamanda askıya alabilir ve F12 tuşuna tıklayarak teste adım adım devam edebilirsiniz. Strateji Test Cihazını Yalnızca açılış fiyatları moduna ayarlarsanız adım bir çubuğa veya Her tik modunu seçtiyseniz bir tike eşit olacaktır. Test hızını da kontrol edebilirsiniz.

Uzman Danışman, manuel olarak bir pozisyon açtıktan/kapattıktan veya Zarar Durdur/Kâr Al seviyeleri ekledikten/değiştirdikten sonra bilgi panelindeki değerlerin güncellenmesini sağlamak için gerçek zamanlı modda test edilmelidir. Çok fazla beklememek adına, Uzman Danışmanı 1 dakikalık bir zaman aralığında çalıştırmanız yeterlidir, böylece alım satım işlemleri her dakika yürütülür.

Bunun yanı sıra, bilgi panelinde pozisyon özelliklerinin adları için başka bir dizi ekledim:

// Array of position property names
string pos_prop_texts[INFOPANEL_SIZE]=
  {
   "Symbol :",
   "Magic Number :",
   "Comment :",
   "Swap :",
   "Commission :",
   "Open Price :",
   "Current Price :",
   "Profit :",
   "Volume :",
   "Stop Loss :",
   "Take Profit :",
   "Time :",
   "Identifier :",
   "Type :"
  };

Bir önceki makalede, SetInfoPanel() fonksiyon kodunu indirgemek için bu diziye ihtiyacımız olacağından bahsetmiştim. Henüz uygulamadıysanız veya kendi başınıza çözemediyseniz, şimdi bunun nasıl yapılabileceğini görebilirsiniz. Pozisyon özellikleriyle ilgili nesneleri oluşturma listesinin yeni uygulaması aşağıdaki gibidir:

//--- List of the names of position properties and their values
   for(int i=0; i<INFOPANEL_SIZE; i++)
     {
      //--- Property name
      CreateLabel(0,0,pos_prop_names[i],pos_prop_texts[i],anchor,corner,font_name,font_size,font_color,x_first_column,y_prop_array[i],2);
      //--- Property value
      CreateLabel(0,0,pos_prop_values[i],GetPropertyValue(i),anchor,corner,font_name,font_size,font_color,x_second_column,y_prop_array[i],2);
     }

SetInfoPanel() fonksiyonunun başında aşağıdaki satırı görebilirsiniz:

//--- Testing in the visualization mode
   if(MQL5InfoInteger(MQL5_VISUAL_MODE))
     {
      y_bg=2;
      y_property=16;
     }

Bu, program o anda görselleştirme modunda test ediliyorsa, programa bilgi panelindeki nesnelerin Y koordinatlarının ayarlanması gerektiğini iletir. Bunun nedeni, Strateji Test Cihazının görselleştirme modunda test yapılırken, Uzman Danışmanın adının grafiğin sağ üst köşesinde gerçek zamanlı olarak görüntülenmemesidir. Dolayısıyla gereksiz girintiler bu şekilde silinebilir.


Sonuç

Şimdilik işimiz bitti. Bir sonraki makalede, alım satım seviyelerini belirlemeye ve değiştirmeye odaklanacağız. Uzman danışman kaynak kodunu buradan indirebilirsiniz: PositionPropertiesTesterEN.mq5.

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

Ekli dosyalar |
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 Özel Bilgi Panelindeki Pozisyon Özellikleri MQL5 Tarif Defteri Özel Bilgi Panelindeki Pozisyon Özellikleri
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".
MQL5 Tarif Defteri: Pozisyon Özelliklerini Elde Etmek için İşlemler Geçmişi ve Fonksiyon Kitaplığı MQL5 Tarif Defteri: Pozisyon Özelliklerini Elde Etmek için İşlemler Geçmişi ve Fonksiyon Kitaplığı
Pozisyon özellikleri ile ilgili önceki makalelerde verilen bilgileri kısaca özetlemenin zamanı geldi. Bu makalemizde, işlemler geçmişine erişimin ardından edinilebilecek özellikleri elde etmek için birkaç ek fonksiyon oluşturacağız. Ayrıca pozisyon ve sembol özelliklerine daha rahat erişmemizi sağlayacak veri yapılarını da öğreneceğiz.
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.