MQL5 Tarif Defteri Özel Bilgi Panelindeki Pozisyon Özellikleri
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ı.
Ş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.
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.
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
- Ücretsiz ticaret uygulamaları
- İşlem kopyalama için 8.000'den fazla sinyal
- Finansal piyasaları keşfetmek için ekonomik haberler
Gizlilik ve Veri Koruma Politikasını ve MQL5.com Kullanım Şartlarını kabul edersiniz