English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
Alım Satım için MQL5'te Aktif Kontrol Panelleri Oluşturma

Alım Satım için MQL5'te Aktif Kontrol Panelleri Oluşturma

MetaTrader 5Uzman Danışmanlar | 15 Aralık 2021, 09:42
106 0
Евгений
Евгений

Giriş

Bir çalışma ortamında, özellikle de hızın ve doğruluğun büyük rol oynadığı yatırımcıların çalışmalarında verimlilik çok önemlidir. Terminali işe hazırlarken, analizleri uygulamak ve bir an önce piyasaya girebilmek için her biri çalışma alanını kendisi için olabildiğince konforlu hale getirir. Ancak işin gerçeği şu ki, geliştiriciler her zaman herkesi memnun edemez ve belirli işlevleri kişinin arzusuna göre ayarlamak imkansızdır.

Örneğin, bir scalper için, saniyenin her bir kesri ve "Yeni Talimat" tuşuna her tıklama önemlidir ve ardından tüm parametrelerin ayarlanması zaman açısından kritik olabilir.

Peki nasıl bir çözüm bulacağız? Çözüm, öğelerin özelleştirilmesinde yatmaktadır; zira MetaTrader 5 "Düğme", "Düzenleme" ve "Etiket" gibi mükemmel bileşenler sağlar. O halde bunu yapalım.


2. Panel Seçenekleri

Öncelikle, bir panel için ne tür işlevlerin gerekli olduğuna karar verelim. Paneli kullanarak temel önemi alım satıma vereceğiz ve bu nedenle aşağıdaki işlevleri ekleyeceğiz:

  • Pozisyon açma
  • Bekleyen bir talimat verme
  • Pozisyonu/talimatı değiştirme
  • Pozisyonu kapatma
  • Bekleyen bir talimatı silme

Ayrıca, renk şeması panelini, yazı tipi boyutlarını ve kaydetme ayarlarını özelleştirme özelliğinin eklenmesinin hiçbir zararı olmaz. Gelecekteki panelin tüm öğelerinin daha ayrıntılı bir açıklamasını verelim. Panelin her işlevi için nesnenin adını, türünü ve amacının açıklamasını belirteceğiz. Her nesnenin adı "ActP" ile başlayacak; bu, nesnenin panele ait olduğunu gösteren bir tür anahtar olacaktır.

2.1. Açık Pozisyonlar

Aşağıda pozisyonun açılması için gerekli tüm parametreleri tanıtacağız ve bir düğmeye tıklayarak bunu uygulayacağız. Bir kutu işaretlenerek etkinleştirilen yardımcı çizgiler, Zararı Durdur ve Kar Al düzeylerini ayarlamamıza yardımcı olacaktır. Yürütme türünün seçimi radyo düğmeleri kullanılarak yapılacaktır.

Adı
Tür
Açıklama
 ActP_buy_button1  Düğme
 Alış işlemi için düğme
 ActP_sell_button1
 Düğme
 Satış işlemi için düğme
 ActP_DealLines_check1
 Bayrak
 Yardımcı çizgileri ayarlama/sıfırlama bayrağı
 ActP_Exe_radio1
 Radyo düğmesi
 Alım satım türünü seçmek için radyo düğmeleri grubu
 ActP_SL_edit1
 Giriş alanı
 Zararı Durdur öğesine giriş yapma alanı
 ActP_TP_edit1
 Giriş alanı
 Kar Al öğesine giriş yapma alanı
 ActP_Lots_edit1
 Giriş alanı
 Tutar girme alanı
 ActP_dev_edit1
 Giriş alanı
 Açılış sırasında kabul edilebilir bir sapma girmek için alan
 ActP_mag_edit1
 Giriş alanı
 Sayı girme alanı
 ActP_comm_edit1  Giriş alanı  Açıklama girme alanı

Tablo 1 Panel öğelerinin listesi, "Alım satım açılışı"

2.2 Bekleyen Bir Talimat Verme

Aşağıda bekleyen bir talimatın verilmesi için gerekli tüm parametreleri tanıtacağız ve bunları bir tuşa basarak yerleştireceğiz. Bir bayrak işaretlenerek etkinleştirilen destekleyici çizgiler, Zararı Durdur, Kar Al, durdurma limiti düzeyleri ve sona erme sürelerinin ayarlanmasına yardımcı olacaktır. Yürütme türü ve sona erme süresi türü seçimi, bir grup radyo düğmesinin yardımıyla gerçekleştirilecektir.

Adı
Tür
Açıklama
 ActP_buy_button2  Düğme
 Al talimatını ayarlama düğmesi
 ActP_sell_button2
 Düğme
 Alım satım talimatını ayarlama düğmesi
 ActP_DealLines_check2
 Bayrak
 Yardımcı çizgileri ayarlama / sıfırma bayrağı
 ActP_lim_check2  Bayrak  Talimat durdurma limitini ayarlama/sıfırlama bayrağı 
 ActP_Exe_radio2
 Radyo düğmesi
 Talimat yürütme türünü seçmek için radyo düğmesi grubu
 ActP_exp_radio2  Radyo düğmesi  Talimat sona erme süresi türünü seçmek için radyo düğmesi grubu
 ActP_SL_edit2
 Giriş alanı
 Zararı Durdur öğesine giriş yapma alanı
 ActP_TP_edit2
 Giriş alanı
 Kar Al öğesine giriş yapma alanı
 ActP_Lots_edit2
 Giriş alanı
 Tutar girme alanı
 ActP_limpr_edit2
 Giriş alanı  Durdurma limiti talimatının fiyatını girme alanı
 ActP_mag_edit2
 Giriş alanı
 Sihirli sayıyı girme alanı
 ActP_comm_edit2  Giriş alanı  Açıklamalar için alan
 ActP_exp_edit2  Giriş alanı  Sona erme süresi girme alanı
 ActP_Pr_edit2  Giriş alanı  Talimat yürütme fiyatını girme alanı 

Tablo 2 "Bekleyen talimatları verme" panelindeki öğelerin listesi

2.3. Alım Satım İşlemlerini Değiştirme / Kapatma

Aşağıda, bir alım satım işleminin değiştirilmesi ve kapatılması için gerekli tüm parametreleri tanıtacağız. Bir kutu işaretlenerek etkinleştirilen yardımcı çizgiler, Zararı Durdur ve Kar Al düzeylerinin kurulumunda bize yardımcı olacaktır. Alım satım işlemlerinin seçimi bir açılır listeden oluşturulacaktır.

Adı
Tür
Açıklama
 ActP_ord_button5   Açılır liste   Alım satım işlemi için seçim listesi
 ActP_mod_button4  Düğme
 Alım satım işlemi değiştirme düğmesi 
 ActP_del_button4
 Düğme
 Alım satım işlemi kapatma düğmesi 
 ActP_DealLines_check4
 Bayrak
 Yardımcı çizgileri ayarlama/sıfırlama bayrağı
 ActP_SL_edit4
 Giriş alanı
 Zararı Durdur öğesine giriş yapma alanı
 ActP_TP_edit4
 Giriş alanı
 Kar Al öğesine giriş yapma alanı
 ActP_Lots_edit4
 Giriş alanı
 Tutar girme alanı 
 ActP_dev_edit4
 Giriş alanı
 Kabul edilebilir bir sapma girmek için alan 
 ActP_mag_edit4
 Giriş alanı
 Sihirli sayıyı görüntüleme alanı (salt okunur)
 ActP_Pr_edit4  Giriş alanı  Açılış fiyatını görüntüleme alanı (salt okunur)

Tablo 3. "Alım satım değişikliği / kapanışı" panelinin öğelerinin listesi

2.4. Talimatları Değiştirme / Kaldırma

Aşağıda, bekleyen talimatların değiştirilmesi ve kaldırılması için gerekli tüm parametreleri tanıtacağız. Bir kutu işaretlenerek etkinleştirilen destekleyici çizgiler, stop, take, stop-limit düzeyleri ve sona erme sürelerinin kurulumunda bize yardımcı olacaktır. Bir grup radyo düğmesinin yardımıyla sona erme sürelerinin türünün seçimi yapılacaktır. Talimatların seçimi, bir açılır listeden oluşturulacaktır.

Adı
Tür
Açıklama
 ActP_ord_button5  Açılır liste  Talimatı seçmek için liste
 ActP_mod_button3  Düğme
 Talimat değiştirme düğmesi 
 ActP_del_button3
 Düğme
 Talimat kaldırma düğmesi 
 ActP_DealLines_check3
 Bayrak
 Yardımcı çizgileri ayarlama/sıfırlama bayrağı
 ActP_exp_radio3  Radyo düğmesi  Bir talimatın sona erme süresi türünü seçmek için radyo düğmeleri grubu
 ActP_SL_edit3
 Giriş alanı
 Zararı Durdur öğesine giriş yapma alanı
 ActP_TP_edit3
 Giriş alanı
 Kar Al öğesine giriş yapma alanı
 ActP_Lots_edit3
 Giriş alanı
 Hacim görüntüleme alanı (salt okunur)
 ActP_limpr_edit3
 Giriş alanı  Stoplimit talimatının fiyatını girmek için alan 
 ActP_mag_edit3
 Giriş alanı
 Sihirli sayıları görüntüleme alanı (salt okunur)
 ActP_comm_edit3  Giriş alanı  Açıklamalar için alan
 ActP_exp_edit3  Giriş alanı  Sona erme süresi girme alanı
 ActP_Pr_edit3  Giriş alanı  Talimat yürütme fiyatını girme alanı 
 ActP_ticket_edit3  Giriş alanı  Talimat bileti görüntüleme alanı (salt okunur) 

Tablo 4. "Talimatların değiştirilmesi / kaldırılması" panelinin öğelerinin listesi

2.5 Ayarlar

Aşağıda, açılır listeden düğmelerin, etiketlerin ve metinlerin rengini seçeceğiz ve çeşitli yazı tipi boyutlarını ayarlayacağız.

Adı
Tür
Açıklama
 ActP_col1_button6  Açılır liste
 Düğmeler için renk seçimi listesi
 ActP_col2_button6
 Açılır liste
 Etiketler için renk seçimi listesi
 ActP_col3_button6
 Açılır liste
 Metin rengi seçimi listesi
 ActP_font_edit6
 Giriş alanı
 Metin boyutunu belirtme alanı

Tablo 5. "Ayarlar" panelinin öğelerinin listesi

Kullanılmıyorsa, paneli küçültme olasılığını oluşturmak için bir düğme de eklenir. "Destek çizgileri" gibi bir enstrümanın varlığını fark etmiş olabilirsiniz. Bunlar nedir ve neden onlara ihtiyacımız var? Bu çizgilerin kullanımı yoluyla, yalnızca fareyi kullanarak bu satırları istenen fiyata/zamana sürükleyerek Zararı Durdur, Kar Al, bekleyen bir talimatın tetiklenme fiyatı, bir durdurma limiti talimatının fiyatı (yatay çizgiler) ve ayrıca ertelenmiş bir talimatın (dikey çizgi) sona erme süresini belirleyebileceğiz.

Sonuçta, görsel bir kurulum, metinsel olandan daha elverişlidir (uygun alana fiyatları / zamanı manuel olarak girerek). Ayrıca, bu çizgiler bize seçilen bir talimatın parametresinin "vurguları" olarak hizmet edecektir. Çok fazla talimat olabileceği için, genellikle fiyatları gösteren standart terminal gölgeli çizgiler çok kafa karıştırıcı olabilir. 


3. Arayüz Oluşturmaya Genel Yaklaşım

Böylece hedefimizi başarılı bir şekilde ortaya koyduk; alım satımda bir grafik asistan biçimi oluşturmak. Bu amaç doğrultusunda, en kullanıcı dostu arayüze ihtiyacımız var. İlk olarak, tüm kontrol öğelerinin (ve çok sayıda olacak) yazılım kullanılarak oluşturulması gerekeceği ve dolayısıyla nesnelerin pozisyonunun ve boyutunun önceden hesaplanması gerektiği net olmalıdır.

Şimdi, nesnelerin koordinatlarını hesaplayarak, üst üste binmemelerine ve net bir şekilde görülebilir olmalarına dikkat ettiğimiz uzun, meşakkatli ve zor bir süreçten geçtiğimizi hayal edin; tüm bu süreçten sonra yeni bir nesne eklemeye ihtiyacımız oldu; bu durumda tüm planımızı yeniden tasarlamamız gerekiyor!

Hızlı Uygulama Geliştirme ortamı (Delphi, C++ Builder vb.) hakkında bilgi sahibi olanlar, en karmaşık kullanıcı arayüzünün ne kadar hızlı oluşturulabileceğini bilirler.

O halde MQL5 kullanarak bunu uygulamaya çalışalım. İlk olarak, fare yardımıyla, kontrol nesnelerini en uygun şekilde konumlandırıyor ve boyutlarını ayarlıyoruz. Ardından, grafikteki tüm nesnelerin özelliklerini okuyan ve bunları bir dosyaya kaydeden basit bir script dosyası yazıyoruz; gerektiğinde bu özellikleri kolayca alabileceğiz ve nesneleri herhangi bir grafik üzerinde tamamen yeniden oluşturabileceğiz.

Script dosyasının kodu şu şekilde görünebilir:

//+------------------------------------------------------------------+
//|                                  Component properties writer.mq5 |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property script_show_inputs

input int interfaceID=1; //input parameter - the identifier of the stored interface
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   //Open file for writing  
   int handle=FileOpen("Active_Panel_scheme_"+IntegerToString(interfaceID)+".bin", FILE_WRITE|FILE_BIN);
   if(handle!=INVALID_HANDLE)
     {
      //We will go all the objects on the chart
      for(int i=0;i<ObjectsTotal(0);i++)
        {
         string name=ObjectName(0,i);
         //And write their properties in the file
         FileWriteString(handle,name,100);
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_TYPE));

         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_XDISTANCE));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_YDISTANCE));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_XSIZE));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_YSIZE));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_COLOR));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_STYLE));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_WIDTH));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_BACK));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_SELECTED));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_SELECTABLE));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_READONLY));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_FONTSIZE));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_STATE));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_BGCOLOR));

         FileWriteString(handle,ObjectGetString(0,name,OBJPROP_TEXT),100);
         FileWriteString(handle,ObjectGetString(0,name,OBJPROP_FONT),100);
         FileWriteString(handle,ObjectGetString(0,name,OBJPROP_BMPFILE,0),100);
         FileWriteString(handle,ObjectGetString(0,name,OBJPROP_BMPFILE,1),100);

         FileWriteDouble(handle,ObjectGetDouble(0,name,OBJPROP_PRICE));
        }
      //Close file
      FileClose(handle);
      Alert("Done!");
     }
  }
//+------------------------------------------------------------------+

Gördüğünüz gibi, kod son derece basittir; tüm grafik nesnelerinin bazı özelliklerini bir ikili dosyaya yazar. En önemli şey, dosyayı okurken kaydedilen özelliklerin sıra düzenini unutmamaktır. 

Script dosyası hazır; arayüzün oluşturulmasına dönelim.

Yapacağımız ilk şey, ana menüyü sekmelerinin türüne göre düzenlemek. Peki neden sekmelere ihtiyacımız var? Çünkü çok fazla nesne var ve hepsini ekrana sığdırmak sorun olurdu. Ve nesneler buna göre gruplandırıldığı için (yukarıdaki tabloya bakınız), her grubu ayrı bir sekmeye yerleştirmek daha kolaydır.   

Böylece, Ekle -> Nesne -> Düğme terminal menüsünü kullanarak, grafiğin üst kısmında ana menümüz olarak işlev görecek olan beş düğme oluşturacağız.

Şekil 1. Panel sekmeleri

Şek. 1 Panel sekmeleri

Nesnelerin "Ctrl" tuşu basılı tutulurken biri seçilip fare ile sürüklenerek kolayca kopyalanabileceğini unutmayın. Bunu yaparak, orijinalinin yerini değiştirmek yerine nesnenin bir kopyasını oluşturacağız.

Nesnelerin adlarına özel dikkat gösterilerek tümünün "ActP" ile başlaması gerektiği unutulmamalıdır. Ayrıca, nesnenin ana menü çubuğuna ait olduğunu gösteren dizenin adına "ana" öğesini ekliyoruz.

Şekil 2. Nesnelerin listesi (panel sekmeleri)

Şekil 2. Nesnelerin listesi (panel sekmeleri)

Benzer şekilde, sekme içeriklerini yeni grafiğe uygulayalım. Her sekmenin içeriği ayrı bir grafiğe yerleştirilmelidir!

"Piyasa" sekmesi:

Şekil 3. "Piyasa" sekmesinin öğeleri

Şekil 3. "Piyasa" sekmesinin öğeleri

"Bekleyen" sekmesi:

Şekil 4. "Bekleyen" sekmesinin öğeleri

Şekil 4. "Bekleyen" sekmesinin öğeleri

Ayarlar sekmesi:

Şekil 5. "Ayarlar" sekmesinin öğeleri

Şekil 5. "Ayarlar" sekmesinin öğeleri

Son "Değiştir / kapat" sekmesi farklıdır; bekleyen talimatları değiştirme / silme ve ayrıca alım satım yatırımlarını değiştirme ve kapatma görevi görecektir. Alım satım işlemlerini içeren işleri ve talimatları içeren işleri iki ayrı alt sekmeye ayırmak mantıklı olacaktır. Öncelikle, çalışmak için bir talimat veya alım satım işlemi seçeceğimiz açılır listeyi etkinleştirecek bir düğme oluşturalım.

Şekil 6. "Değiştir/Kapat" sekmesinin öğeleri

Şekil 6. "Değiştir/Kapat" sekmesinin öğeleri" tab

Daha sonra, alt sekmeler oluşturuyoruz. Alım satım işlemleriyle çalışmak için:

Şekil 7. Pozisyonlarla çalışma öğeleri

Şekil 7. Pozisyonlarla çalışma öğeleri

Ve talimatlarla çalışmak için:

Şekil 8. Talimatlarla çalışma alt sekmesi

Şekil 8. Talimatlarla çalışma alt sekmesi

Hepsi bu kadar, arayüz oluşturuldu.

Her sekmeyi ayrı bir dosyaya kaydetmek için script dosyasını grafiklerin her birine uygularız. "interfaceID" giriş parametresi her sekme için farklı olmalıdır:

  • 0 - Giriş sayfası
  • 1 - Piyasa
  • 2 - Bekleyen
  • 3 - Alım satım / talimat seçim listesini etkinleştirmek için düğme
  • 4 - Ayarlar
  • 6 - Alım satım işlemleriyle çalışmak için alt sekme
  • 7 - Talimatlarla çalışmak için alt sekme

5 numaralı sekme, ana menüdeki "Pencereyi simge durumuna küçült" düğmesine karşılık gelir; bu nedenle üzerinde herhangi bir nesne yoktur ve onu atlayabiliriz.

Tüm bu işlemlerden sonra, terminalin -> MQL5 -> dizin klasöründe aşağıdaki dosyalar görünecektir:

Şekil 8. Panel şemalarının dosya listesi

Şekil 9. Panel şemalarının dosya listesi


4. Arayüz Öğelerini İndirme

Artık arayüz öğeleri dosyalarda saklanır ve çalıştırılmaya hazırdır. İlk olarak panelimizin konumlandırılacağı yeri belirleyelim.  Doğrudan ana grafiğe konumlandırırsak bu, fiyatlar grafiğini bloke edecektir; bu, çok elverişsizdir olur. Bu nedenle paneli ana grafiğin alt penceresine yerleştirmek en mantıklısı olacaktır. Bir gösterge bu bölmeyi oluşturabilir.

O halde, onu oluşturalım.

#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "http://www.mql5.com"
#property version   "1.00"
#property indicator_separate_window //place the indicator in a separate window

int OnInit()
  {
//--- indicator buffers mapping
   //Set the short name of the indicator
   IndicatorSetString(INDICATOR_SHORTNAME, "AP");
//---
   return(0);
  }

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime& time[],
                const double& open[],
                const double& high[],
                const double& low[],
                const double& close[],
                const long& tick_volume[],
                const long& volume[],
                const int& spread[])
  {
//---
//--- return value of prev_calculated for next call
   return(rates_total);
  }

Kod çok basittir; zira bu göstergenin ana işlevi çeşitli hesaplamalar yapmaktan ziyade alt pencerelerin oluşturulmasıdır. Yapacağımız tek şey, alt penceresini bulabileceğimiz göstergenin "kısa" bir adını yüklemektir. Göstergeye bir grafik derleyip uygulayacağız ve bir pencere görünecek.

Şimdi Expert Advisor paneline odaklanalım. Yeni bir Expert Advisor oluşturacağız.

OnInit() işlevi aşağıdaki işleçleri içerecektir:

double Bid,Ask;         //variables for current prices
datetime time_current;  //time of last tick
int wnd=-1;             //index of the window with an indicator
bool last_loaded=false; //flag indicating whether it's a first initialization or not
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   //Start the timer at intervals of 1 second
   EventSetTimer(1); 
   //Get the latest prices
   get_prices();
   //Define the window with an indicator
   wnd=ChartWindowFind(0,"AP");
   //If the first initialization - create interface
   if(!last_loaded) create_interface();
//---
   return(0);
  }

Burada bir zamanlayıcı başlatıyoruz (bunun neden yapıldığı aşağıda açıklanacaktır), ChartWindowFind'ı kullanarak piyasadaki en son fiyatları alın, gösterge penceresini bulun ve bunu bir değişken olarak kaydedin. last_loaded bayrağı - bunun Expert Advisor'ın ilk başlatılışı olup olmadığını gösterir. Bu bilgiler, yeniden başlatma sırasında arayüzün yeniden yüklenmesini önlemek için gereklidir. 

create_interface() işlevi şu şekilde görünür:

//+------------------------------------------------------------------+
//| Function of the interface creation                               |
//+------------------------------------------------------------------+
void create_interface()
  {
   //if reset settings is selected
   if(Reset_Expert_Settings)
     {
     //Reset
      GlobalVariableDel("ActP_buttons_color");
      GlobalVariableDel("ActP_label_color");
      GlobalVariableDel("ActP_text_color");
      GlobalVariableDel("ActP_font_size");
     }

   //Create the main menu interface
   ApplyScheme(0);
   //Create the interface tab "Market"
   ApplyScheme(1);
   //Set all objects as unmarked
   Objects_Selectable("ActP",false);
   //redraw the chart
   ChartRedraw();
  }

İlk adım, "ayarları sıfırla" giriş parametresini kontrol etmektir ve yüklüyse, ayarlardan sorumlu genel değişkenleri kaldırın. Bu işlemin paneli nasıl etkilediği aşağıda açıklanacaktır. Ayrıca, ApplyScheme () işlevi bir dosyadan bir arayüz oluşturacaktır. 

//+------------------------------------------------------------------+
//| The function for the interface loading                           |
//| ID - ID of the saved interface                                   |
//+------------------------------------------------------------------+
bool ApplyScheme(int ID)
  {
   string fname="Active_Panel_scheme_custom_"+IntegerToString(ID)+".bin";
   //download the standard scheme if there isn't saved scheme 
   if(!FileIsExist(fname)) fname="Active_Panel_scheme_"+IntegerToString(ID)+".bin";
   //open file for reading
   int handle=FileOpen(fname,FILE_READ|FILE_BIN);
   //file opened
   if(handle!=INVALID_HANDLE)
     {
      //Loading all objects
      while(!FileIsEnding(handle))
        {
         string obj_name=FileReadString(handle,100);
         int _wnd=wnd;
         //the auxiliary lines are in the main window
         if(StringFind(obj_name,"line")>=0) _wnd=0;
         ENUM_OBJECT obj_type=FileReadInteger(handle);
         //creating object
         ObjectCreate(0, obj_name, obj_type, _wnd, 0, 0);   
         //and apply the properties 
         ObjectSetInteger(0,obj_name,OBJPROP_XDISTANCE,FileReadInteger(handle));
         ObjectSetInteger(0,obj_name,OBJPROP_YDISTANCE,FileReadInteger(handle));
         ObjectSetInteger(0,obj_name,OBJPROP_XSIZE,FileReadInteger(handle));
         ObjectSetInteger(0,obj_name,OBJPROP_YSIZE,FileReadInteger(handle));
         ObjectSetInteger(0,obj_name,OBJPROP_COLOR,FileReadInteger(handle));
         ObjectSetInteger(0,obj_name,OBJPROP_STYLE,FileReadInteger(handle));
         ObjectSetInteger(0,obj_name,OBJPROP_WIDTH,FileReadInteger(handle));
         ObjectSetInteger(0,obj_name,OBJPROP_BACK,FileReadInteger(handle));
         ObjectSetInteger(0,obj_name,OBJPROP_SELECTED,FileReadInteger(handle));
         ObjectSetInteger(0,obj_name,OBJPROP_SELECTABLE,FileReadInteger(handle));
         ObjectSetInteger(0,obj_name,OBJPROP_READONLY,FileReadInteger(handle));
         ObjectSetInteger(0,obj_name,OBJPROP_FONTSIZE,FileReadInteger(handle));
         ObjectSetInteger(0,obj_name,OBJPROP_STATE,FileReadInteger(handle));
         ObjectSetInteger(0,obj_name,OBJPROP_BGCOLOR,FileReadInteger(handle));

         ObjectSetString(0,obj_name,OBJPROP_TEXT,FileReadString(handle,100));
         ObjectSetString(0,obj_name,OBJPROP_FONT,FileReadString(handle,100));
         ObjectSetString(0,obj_name,OBJPROP_BMPFILE,0,FileReadString(handle,100));
         ObjectSetString(0,obj_name,OBJPROP_BMPFILE,1,FileReadString(handle,100));

         ObjectSetDouble(0,obj_name,OBJPROP_PRICE,FileReadDouble(handle));

         //Set color for the objects
         if(GlobalVariableCheck("ActP_buttons_color") && obj_type==OBJ_BUTTON)
            ObjectSetInteger(0,obj_name,OBJPROP_BGCOLOR,GlobalVariableGet("ActP_buttons_color"));
         if(GlobalVariableCheck("ActP_label_color") && obj_type==OBJ_LABEL)
            ObjectSetInteger(0,obj_name,OBJPROP_COLOR,GlobalVariableGet("ActP_label_color"));
         if(GlobalVariableCheck("ActP_text_color") && (obj_type==OBJ_EDIT || obj_type==OBJ_BUTTON))
            ObjectSetInteger(0,obj_name,OBJPROP_COLOR,GlobalVariableGet("ActP_text_color"));
         if(GlobalVariableCheck("ActP_font_size") && (obj_type==OBJ_EDIT || obj_type==OBJ_LABEL))
            ObjectSetInteger(0,obj_name,OBJPROP_FONTSIZE,GlobalVariableGet("ActP_font_size"));
         //Set global variable font size
         if(obj_name=="ActP_font_edit6" && GlobalVariableCheck("ActP_font_size"))
            ObjectSetString(0,obj_name,OBJPROP_TEXT,IntegerToString(GlobalVariableGet("ActP_font_size")));
        }
      //Close file
      FileClose(handle);
      return(true);
     }
   return(false);
  }

Bir kez daha, bu konuda karmaşık herhangi bir şey yok. İşlev, önceden kaydedilmiş bir arayüz şeması ile istenen dosyayı açacak ve bunu, daha önce tanımladığımız pencerede (gösterge penceresi) oluşturacaktır. Ayrıca nesnelerin renklerini ve yazı tipi boyutlarını terminalin genel değişkenlerinden seçiyoruz. 

Objects_Selectable () işlevi, düğmelerin hareketlerini açmak ve gerekli bir nesnenin yanlışlıkla silinmesini önlemek için yardımcı çizgiler hariç tüm nesneleri işaretsiz hale getirir.

//+------------------------------------------------------------------+
//| Function of setting objects as unselectable                      |
//+------------------------------------------------------------------+
void  Objects_Selectable(string IDstr,bool flag)
  {
   //Check all the objects
   for(int i=ObjectsTotal(0);i>=0;i--)
     {
      string n=ObjectName(0,i);
      //If the object belongs to the panel
      if(StringFind(n,IDstr)>=0)
        {
         //Lines remain untouched
         if(!flag)
            if(StringFind(n,"line")>-1) continue; 
         //Set everything unselectable except the lines
         ObjectSetInteger(0,n,OBJPROP_SELECTABLE,flag); 
        }
     }
  }

Şimdi OnTick() işlevine bakalım. Bu, piyasadaki en son fiyatları elde etmemize yardımcı olacaktır.

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   //Get the latest prices
   get_prices();
  }

get_prices() işlevi şu şekildedir:

//+------------------------------------------------------------------+
//| Function obtain information on tick                              |
//+------------------------------------------------------------------+
void get_prices()
  {
   MqlTick tick;
   //if the tick was
   if(SymbolInfoTick(Symbol(),tick))
     {
      //obtain information
      Bid=tick.bid;
      Ask=tick.ask;
      time_current=tick.time;
     }
  }

Ve OnDeinit () hakkında şunu unutmayın:

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   //if the deinitialisation reason isn't the timeframe or symbol change
   if(reason!=REASON_CHARTCHANGE)
     {
      //reset initialization flag
      last_loaded=false;  
      //Delete all panel objects
      ObjectsDeleteAll_my("ActP");
      //Delete files with the saved state of the tabs
      FileDelete("Active_Panel_scheme_custom_1.bin");
      FileDelete("Active_Panel_scheme_custom_2.bin");
      FileDelete("Active_Panel_scheme_custom_3.bin");
      FileDelete("Active_Panel_scheme_custom_4.bin");
      FileDelete("Active_Panel_scheme_custom_5.bin");
     }
   //otherwise set a flag
   else last_loaded=true;
   //stop the timer
   EventKillTimer();
  }

İlk önce başlatmadan kaldırmanın nedenini kontrol edin: Bu, bir zaman dilimi ve / veya sembollerdeki bir değişiklikten kaynaklanıyorsa panel öğesini silmeyeceğiz. Diğer tüm durumlarda, ObjectsDeleteAll_my () işlevini kullanarak tüm öğeleri kaldırın.

//+------------------------------------------------------------------+
//| The function deletes all panel objects                           |
//| IDstr - object identifier                                        |
//+------------------------------------------------------------------+
void  ObjectsDeleteAll_my(string IDstr)
  {
   //check all the objects
   for(int i=ObjectsTotal(0);i>=0;i--)
     {
      string n=ObjectName(0,i);
      //if the name contains the identifier - remove the object
      if(StringFind(n,IDstr)>=0) ObjectDelete(0,n);
     }
  }

Expert Advisor'ı derleyip çalıştırdıktan sonra aşağıdaki sonucu elde ederiz:

Şekil 10. Expert Advisor çalışma örneği

Şekil 10. Expert Advisor çalışma örneği

Ancak, bu nesnelerin işlemimize yanıt vermesini sağlayana kadar tüm bunlardan çok az fayda görürüz.


5. Olay İşleme

Arayüz oluşturuldu; şimdi onu çalıştırmamız gerekiyor. Nesnelerle yaptığımız tüm işlemlerimiz belirli olaylar üretir. OnChartEvent işlevi OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam), ChartEvent olaylarının işleme mekanizmasıdır. Olayların arasından şunlarla ilgileniyoruz: 

  • CHARTEVENT_CLICK - grafiğe tıklayın
  • CHARTEVENT_OBJECT_ENDEDIT - giriş alanını düzenlemeyi bitirin 
  • CHARTEVENT_OBJECT_CLICK - grafik nesnesine tıklayın

Bizim durumumuzda, id işlevinin parametresi olayın kimliğini gösterir, sparam bu olayı oluşturan nesnenin adını gösterir; diğer tüm parametreler bizi ilgilendirmiyor.

Keşfedeceğimiz ilk olay: Ana menü düğmesine tıklayın.

5.1. Ana Menü Olaylarını İşleme

Ana menünün beş düğmeden oluştuğunu hatırlayın. Bunlardan birine tıklandığında bunun basılı bir moda geçmesi, bizi doğru arayüze yönlendirmesi ve uygun sekmeleri yüklemesi gerekir. Ardından diğer menü düğmelerinin tümü basılmamış moda geçmelidir.

//+------------------------------------------------------------------+
//| Event handlers                                                   |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
...
   //Event - click on a graphic object
   if(id==CHARTEVENT_OBJECT_CLICK)
   {
   ...
       //main menu button click
      if(sparam=="ActP_main_1") {Main_controls_click(1); ChartRedraw(); return;}
       //Here we execute the corresponding operators
      if(sparam=="ActP_main_2") {Main_controls_click(2); ChartRedraw(); return;}
      if(sparam=="ActP_main_3") {Main_controls_click(3); ChartRedraw(); return;}
      if(sparam=="ActP_main_4") {Main_controls_click(4); ChartRedraw(); return;}
      if(sparam=="ActP_main_5") {Main_controls_click(5); ChartRedraw(); return;}
   ...   
   }
...
}

Menü düğmesine tıklandığında, Main_controls_click() işlevini gerçekleştirdik. ChartRedraw() işlevini kullanarak grafiği yeniden çizelim ve işlevi tamamlayalım. Yürütmeyi tamamlamalıyız; zira aynı anda yalnızca bir nesneye tıklanabilir; bu nedenle diğer tüm uygulamalar CPU zamanının boşa harcanmasına neden olacaktır.

//+------------------------------------------------------------------+
//| Tab processor                                                    |
//| ID - index of clicked tab                                        |
//+------------------------------------------------------------------+
void Main_controls_click(int ID)
  {
   int loaded=ID;
   //we will go all tabs
   for(int i=1;i<6;i++)
     {
      //for all except the selected set inactive
      if(i!=ID) 
        {
         //also remember the last active tab
         if(ObjectGetInteger(0,"ActP_main_"+IntegerToString(i),OBJPROP_STATE)==1) loaded=i;
         ObjectSetInteger(0,"ActP_main_"+IntegerToString(i),OBJPROP_STATE,0);
        }
     }
//if(loaded==ID) return;
   //set an active state for the selected
   ObjectSetInteger(0,"ActP_main_"+IntegerToString(ID),OBJPROP_STATE,1);
   //delete the drop-down lists
   DeleteLists("ActP_orders_list_"); 
   DeleteLists("ActP_color_list_");
   //and set the list buttons to the unpressed state
   ObjectSetInteger(0,"ActP_ord_button5",OBJPROP_STATE,0);
   ObjectSetInteger(0,"ActP_col1_button6",OBJPROP_STATE,0);
   ObjectSetInteger(0,"ActP_col2_button6",OBJPROP_STATE,0);
   ObjectSetInteger(0,"ActP_col3_button6",OBJPROP_STATE,0);
   //save state of the last active tab
   SaveScheme(loaded);
   //remove old tab
   DeleteScheme("ActP");
   //and load a new
   ApplyScheme(ID);
   //Set all objects as unselected
   Objects_Selectable("ActP",false);
  }

Objects_Selectable() ve ApplyScheme() işlevleriyle tanıştık, daha sonra DeleteLists() işlevine döneceğiz.

SaveScheme() işlevi, yeniden yükleme sırasında nesnelerin tüm özelliklerini koruması için bir arayüz dosyası kaydeder:

//+------------------------------------------------------------------+
//| Interface saving function                                        |
//+------------------------------------------------------------------+
void SaveScheme(int interfaceID)
  {
   //open file for writing
   int handle=FileOpen("Active_Panel_scheme_custom_"+IntegerToString(interfaceID)+".bin",FILE_WRITE|FILE_BIN);
   //if file opened
   if(handle!=INVALID_HANDLE)
     {
      //go all the chart objects
      for(int i=0;i<ObjectsTotal(0);i++)
        {
         string name=ObjectName(0,i);
         //if the object belongs to the panel
         if(StringFind(name,"ActP")<0) continue;
         //and it isn't a tab
         if(StringFind(name,"main")>=0) continue; 
         //write the object properties to a file
         FileWriteString(handle,name,100);
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_TYPE));

         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_XDISTANCE));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_YDISTANCE));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_XSIZE));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_YSIZE));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_COLOR));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_STYLE));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_WIDTH));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_BACK));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_SELECTED));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_SELECTABLE));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_READONLY));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_FONTSIZE));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_STATE));
         FileWriteInteger(handle,ObjectGetInteger(0,name,OBJPROP_BGCOLOR));

         FileWriteString(handle,ObjectGetString(0,name,OBJPROP_TEXT),100);
         FileWriteString(handle,ObjectGetString(0,name,OBJPROP_FONT),100);
         FileWriteString(handle,ObjectGetString(0,name,OBJPROP_BMPFILE,0),100);
         FileWriteString(handle,ObjectGetString(0,name,OBJPROP_BMPFILE,1),100);

         FileWriteDouble(handle,ObjectGetDouble(0,name,OBJPROP_PRICE));
        }
      //Close file
      FileClose(handle);
     }
  }

DeleteScheme() işlevi, sekme nesnelerini kaldırır.

//+------------------------------------------------------------------+
//| Function to delete all the panel objects, except tabs            |
//+------------------------------------------------------------------+
void  DeleteScheme(string IDstr)
  {
   //we will go through all the objects
   for(int i=ObjectsTotal(0);i>=0;i--)
     {
      string n=ObjectName(0,i);
      //remove everything but the tab
      if(StringFind(n,IDstr)>=0 && StringFind(n,"main")<0) ObjectDelete(0,n);
     }
  }

Böylece, Main_controls_click() işlevini gerçekleştirerek eski sekmeyi kaldıracağız, önceden kaydedeceğiz ve yeni bir tane yükleyeceğiz.

Expert Advisor'ı derleyerek sonuçları göreceğiz.

Şimdi ana menü düğmesine tıklayacağız, yeni sekmeleri yükleyerek onları orijinal sekmelerin durumunda tutacağız.

Şekil 11. "Bekleyen" sekmesinin öğeleri

Şekil 11. "Bekleyen" sekmesinin öğeleri

Şekil 12 "Değiştir/Kapat" sekmesinin öğeleri

Şekil 12. "Değiştir/Kapat" sekmesinin öğeleri


Şekil 12 "Ayarlar" sekmesinin öğeleri

Şekil 13. "Ayarlar" sekmesinin öğeleri

Bu noktada, ana menünün işlemesini bitirebiliriz; zira artık işlevlerini tam olarak yerine getiriyor.

5.2. "Bayrak" Bileşen Olayını İşleme

Yardımcı çizgilerin ve durdurma limiti talimatlarının ayarı "bayrak" bileşenleri kullanılarak yapılır, ancak bu, MT5'in grafik nesneleri listesinde değildir. O halde, onu oluşturalım. Gerçekte "açık" ve "kapalı" durumuna sahip bir resim olan bir "grafik etiket" nesnesi vardır. Durum, nesneye tıklanarak değiştirilebilir. Her durum için ayrı bir resim ayarlanabilir. Her durum için bir resim seçin:

  •  Etkinleştirildi
  •  Devre dışı bırakıldı

Resimleri nesnenin özelliklerinde ayarlayalım:

Şekil 13 "Bayrak" öğesinin özelliklerini ayarlama

Şekil 13. "Bayrak" öğesinin özelliklerini ayarlama

Resimlerin listede yer alabilmesi için "Terminal klasörü-> MQL5-> Resimler" klasöründe konumlandırılması ve ".Bmp" uzantılı olması gerektiğini hatırlatmak isteriz.

Bir nesneye tıkladığınızda meydana gelen olayları işlemeye dönelim. Alım satım işleminin açılışında yardımcı çizgilerin yerleştirilmesinden sorumlu olan bayrak örneğini kullanacağız.

      //click on the flag of the setting of auxiliary lines during transaction opening
      if(sparam=="ActP_DealLines_check1")
      {
         //Check the flag state
         bool selected=ObjectGetInteger(0,sparam,OBJPROP_STATE);
         //If the flag is set
         if(selected)
         {
            //Retrieve the value of the stop loss and take profit from the input fields
            string SL_txt=ObjectGetString(0, "ActP_SL_edit1", OBJPROP_TEXT);
            string TP_txt=ObjectGetString(0, "ActP_TP_edit1", OBJPROP_TEXT);
            double val_SL, val_TP;
            
            //If the Stop field is not empty
            //save the value
            if(SL_txt!="")
               val_SL=StringToDouble(SL_txt);

            //if empty
            else
            {
               //Take the max. and min. prices of chart
               double pr_max=ChartGetDouble(0, CHART_PRICE_MAX);
               double pr_min=ChartGetDouble(0, CHART_PRICE_MIN);
               //Set the stop at the 1/3 of the chart price range
               val_SL=pr_min+(pr_max-pr_min)*0.33;
            }   
            
            //Similarly processes the Take
            if(TP_txt!="")
               val_TP=StringToDouble(TP_txt);
            else
            {
               double pr_max=ChartGetDouble(0, CHART_PRICE_MAX);
               double pr_min=ChartGetDouble(0, CHART_PRICE_MIN);
               val_TP=pr_max-(pr_max-pr_min)*0.33;
            }      
            //Move the line to new positions
            ObjectSetDouble(0, "ActP_SL_line1", OBJPROP_PRICE, val_SL);  
            ObjectSetDouble(0, "ActP_TP_line1", OBJPROP_PRICE, val_TP);  
         }
          //If the flag is unset
         else
         {
             //remove the lines
            ObjectSetDouble(0, "ActP_SL_line1", OBJPROP_PRICE, 0);
            ObjectSetDouble(0, "ActP_TP_line1", OBJPROP_PRICE, 0);
         }
          //redraw the chart
         ChartRedraw();
          //and finish the function 
         return;
      }

Bekleyen talimatların kapatılması / değiştirilmesi sekmesinde yardımcı çizgilerin işlenmesinden ve yüklenmesinden sorumlu olan bayraklar için de aynı yöntem kullanılır. Bu nedenle, bu makalede onlarla ilgili ayrıntılara girmeyeceğiz. Bunlar hakkında bilgi sahibi olmak isteyenler Expert Advisor kodunu kullanabilirler.

"Bekleyen" sekmesindeki stoplimit talimatları bayrağının ayarı aşağıdaki işleyiciyi içerir:

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
...

   //Event - click on a graphic object
   if(id==CHARTEVENT_OBJECT_CLICK)
   {
   ...
      //Click on the orders stoplimit check box
      if(sparam=="ActP_limit_check2")
      {
         //Check the flag state
         bool selected=ObjectGetInteger(0,sparam,OBJPROP_STATE);
         if(selected) //if flag is set
         {
            //set the new color for the price edit
            ObjectSetInteger(0, "ActP_limpr_edit2", OBJPROP_BGCOLOR, White);
            //enable it for the edit
            ObjectSetInteger(0, "ActP_limpr_edit2", OBJPROP_READONLY, false);
            //установим в поле значение текущей цены
            //Set the current price as the field value
            ObjectSetString(0, "ActP_limpr_edit2", OBJPROP_TEXT, DoubleToString(Bid, _Digits));
            //if the auxiliary lines are allowed
            //move them
            if(ObjectGetInteger(0, "ActP_DealLines_check2", OBJPROP_STATE)==1)
               ObjectSetDouble(0, "ActP_lim_line2", OBJPROP_PRICE, Bid);
         }  
          //if flag is unset
         else
         {
            //set the field unavailable for editing
            ObjectSetInteger(0, "ActP_limpr_edit2", OBJPROP_BGCOLOR, LavenderBlush);
            //set the field color
            ObjectSetInteger(0, "ActP_limpr_edit2", OBJPROP_READONLY, true);
            //and "empty" text
            ObjectSetString(0, "ActP_limpr_edit2", OBJPROP_TEXT, "");
            //if the auxiliary lines are allowed
            //move them to the zero point
            if(ObjectGetInteger(0, "ActP_DealLines_check2", OBJPROP_STATE)==1)
               ObjectSetDouble(0, "ActP_lim_line2", OBJPROP_PRICE, 0);
         }
      }       
   ...   
   }
...
}

Artık bayraklarla çalışmayı tamamladık. Kendi üretimimiz olan şu nesneyi ele alalım; "radyo düğmeleri grubu".

5.3. "Radyo düğmeleri Grubu" Bileşen Olayını İşleme

Bu bileşeni kullanarak, bir alım satım işleminin türünü ve talimatın sona erme süresi türünü seçiyoruz. Tıpkı bayraklarda olduğu gibi, grafik etiketleri kullanacağız, ancak bu kez yeni resimlerle birlikte. 

  • Etkinleştirildi
  • Devre dışı bırakıldı

Ancak burada sorun, tıkladığınız düğme dışındaki tüm radyo düğmelerini etkin olmayan bir duruma sıfırlama gerekliliği nedeniyle karmaşıktır. Talimat yürütme türünün radyo düğmesi örneğini göz önünde bulundurun:

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
...
   //event - click on a graphic object
   if(id==CHARTEVENT_OBJECT_CLICK)
   {
   ...
      //click on radion button 1 - order execution type
      if(sparam=="ActP_Exe1_radio2")
      {
         //check the radio button state
         bool selected=ObjectGetInteger(0,sparam,OBJPROP_STATE);
         //set the appropriate state
         ObjectSetInteger(0,sparam,OBJPROP_STATE, 1);
         //if it selected
         if(selected)
         {
            //reset the other radio buttons
            ObjectSetInteger(0, "ActP_Exe2_radio2", OBJPROP_STATE, false);
            ObjectSetInteger(0, "ActP_Exe3_radio2", OBJPROP_STATE, false);
            //redraw the chart
            ChartRedraw();
            //finish the execution of function
            return;
         }
         //redraw the chart
         ChartRedraw();
         //finish the execution of function
         return;
      }
 
       //Similarly for the radio button 2
      if(sparam=="ActP_Exe2_radio2") 
      {
         bool selected=ObjectGetInteger(0,sparam,OBJPROP_STATE);
         ObjectSetInteger(0,sparam,OBJPROP_STATE, 1);
         if(selected)
         {
            ObjectSetInteger(0, "ActP_Exe1_radio2", OBJPROP_STATE, false);
            ObjectSetInteger(0, "ActP_Exe3_radio2", OBJPROP_STATE, false);
            ChartRedraw();
            return;
         }
         ChartRedraw();
         return;
      }   

       //Similarly for the radio button 3
      if(sparam=="ActP_Exe3_radio2") 
      {
         bool selected=ObjectGetInteger(0,sparam,OBJPROP_STATE);
         ObjectSetInteger(0,sparam,OBJPROP_STATE, 1);
         if(selected)
         {
            ObjectSetInteger(0, "ActP_Exe1_radio2", OBJPROP_STATE, false);
            ObjectSetInteger(0, "ActP_Exe2_radio2", OBJPROP_STATE, false);
            ChartRedraw();
            return;
         }
         ChartRedraw();
         return;
      }     
   ...   
   }
...
}

Talimat sona erme süresi türü radyo düğmeleri, yalnızca üçüncü düğmeye tıkladığınızda ek bir adım gerçekleştirmeniz gerektiği gerçeğinde farklılık gösterir; bir talimatın sona erme süresinin giriş saatinde yeni bir tarih ayarlamanız gerekir:

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
...
   //Event - click on a graphic object
   if(id==CHARTEVENT_OBJECT_CLICK)
   {
   ...
       //Click on the 3rd radio button - order expiration date
      if(sparam=="ActP_exp3_radio2")
      {
         //checking it state
         bool selected=ObjectGetInteger(0,sparam,OBJPROP_STATE);
         ObjectSetInteger(0,sparam,OBJPROP_STATE, 1);
         //if it selected
         if(selected)
         {
            //reset the remained radio buttons
            ObjectSetInteger(0, "ActP_exp1_radio2", OBJPROP_STATE, false);
            ObjectSetInteger(0, "ActP_exp2_radio2", OBJPROP_STATE, false);
            //set the new date to the date edit field
            ObjectSetInteger(0, "ActP_exp_edit2", OBJPROP_BGCOLOR, White);
            ObjectSetInteger(0, "ActP_exp_edit2", OBJPROP_READONLY, false);
            ObjectSetString(0, "ActP_exp_edit2", OBJPROP_TEXT, TimeToString(time_current));
            //if auxiliary lines are allowed 
            //set the new time line
            if(ObjectGetInteger(0, "ActP_DealLines_check2", OBJPROP_STATE)==1)
               ObjectSetInteger(0, "ActP_exp_line2", OBJPROP_TIME, time_current);
            ChartRedraw();
            return;
         }

          //if it isn't selected
         else
         {
            //set the edit field as not available for editing
            ObjectSetInteger(0, "ActP_exp_edit2", OBJPROP_BGCOLOR, LavenderBlush);
            ObjectSetInteger(0, "ActP_exp_edit2", OBJPROP_READONLY, true);
            //remove the auxiliary line
            if(ObjectGetInteger(0, "ActP_DealLines_check2", OBJPROP_STATE)==1)
               ObjectSetInteger(0, "ActP_exp_line2", OBJPROP_TIME, 0);
         }      
         ChartRedraw();
         return;
   ...   
   }
...
}

Artık radyo düğmeleriyle çalışmayı tamamladık.

5.4. Açılır listelerin olaylarını oluşturma ve işleme

Değiştirme / kapatma / kaldırma ve renk seçimleri paneli için talimat / alım satım işlemi seçimi için açılır listeyi kullanacağız. Alım satım işlemleri / talimatlar listesiyle başlayalım.

"Değiştirme / Kapatma" sekmesinde görünen ilk şey "Bir talimat seç " etiketli bir düğmedir; bu, listeyi etkinleştiren düğme olacaktır. Bunun üzerine tıkladığınızda açılır liste açılmalı ve seçimimizi yaptıktan sonra tekrar kapanmalıdır.  Bu düğmenin CHARTEVENT_OBJECT_CLICK işleyicisine bir göz atalım:

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
...
   //event - click on a graphic object
   if(id==CHARTEVENT_OBJECT_CLICK)
   {
   ...
      //click on the drop-down list activate button (order select)

      if(sparam=="ActP_ord_button5")
      {
         //check status
         bool selected=ObjectGetInteger(0,sparam,OBJPROP_STATE);
         //the list is activated
         if(selected)// the list is selected
         {
            //delete interface
            DeleteScheme("ActP", true);
            //arrays for serving the information about the orders
            string info[100];
            //array for the tickets
            int tickets[100];
            //initialize it
            ArrayInitialize(tickets, -1);
            //get orders info
            get_ord_info(info, tickets);
            //create the list
            create_list(info, tickets);
         }
          //the list isn't active
         else
         {
            //delete it
            DeleteLists("ActP_orders_list_");
         }
          //redraw the chart
         ChartRedraw();
          //finish the function
         return;
      }      
   ...   
   }
...
}

Öncelikli hedefimiz, alım satım işlemlerinin/talimatların piyasada olup olmadığını belirlemek ve varsa bunlardan bilgi çıkarıp listede görüntülemektir. get_ord_info() işlevi, bu rolü gerçekleştirir:

//+------------------------------------------------------------------+
//| The function for obtaining the information about orders          |
//+------------------------------------------------------------------+
void get_ord_info(string &info[],int &tickets[])
  {
   //initialize the counter
   int cnt=0;
   string inf;
   //if there is an open position
   if(PositionSelect(Symbol()))
     {
     //combine all order infomation in a single line
      double vol=PositionGetDouble(POSITION_VOLUME);
      int typ=PositionGetInteger(POSITION_TYPE);
      if(typ==POSITION_TYPE_BUY) inf+="BUY ";
      if(typ==POSITION_TYPE_SELL) inf+="SELL ";
      inf+=DoubleToString(vol, MathCeil(MathAbs(MathLog(vol)/MathLog(10))))+" lots";
      inf+=" at "+DoubleToString(PositionGetDouble(POSITION_PRICE_OPEN), Digits());
      //write the results
      info[cnt]=inf;
      tickets[cnt]=0;
      //increment the counter
      cnt++;
     }

   //all orders
   for(int i=0;i<OrdersTotal();i++)
     {
      //get ticket
      int ticket=OrderGetTicket(i);
      //if order symbol is equal to chart symbol
      if(OrderGetString(ORDER_SYMBOL)==Symbol())
        {
         //combine all order infomation in a single line
         inf="#"+IntegerToString(ticket)+" ";
         int typ=OrderGetInteger(ORDER_TYPE);
         double vol=OrderGetDouble(ORDER_VOLUME_CURRENT);
         if(typ==ORDER_TYPE_BUY_LIMIT) inf+="BUY LIMIT ";
         if(typ==ORDER_TYPE_SELL_LIMIT) inf+="SELL LIMIT ";
         if(typ==ORDER_TYPE_BUY_STOP) inf+="BUY STOP ";
         if(typ==ORDER_TYPE_SELL_STOP) inf+="SELL STOP ";
         if(typ==ORDER_TYPE_BUY_STOP_LIMIT) inf+="BUY STOP LIMIT ";
         if(typ==ORDER_TYPE_SELL_STOP_LIMIT) inf+="SELL STOP LIMIT ";
         inf+=DoubleToString(vol, MathCeil(MathAbs(MathLog(vol)/MathLog(10))))+" lots";
         inf+=" at "+DoubleToString(OrderGetDouble(ORDER_PRICE_OPEN), Digits());
         //write the results
         info[cnt]=inf;
         tickets[cnt]=ticket;
         //increment the counter
         cnt++;
        }
     }
  }

Bu, bir blok bilgisinde birleşecek ve bilet ve alım satım talimatı verecektir.

Ayrıca create_list() işlevi bu bilgilere dayanarak bir liste oluşturacaktır:

//+------------------------------------------------------------------+
//| The function creates list of positions                           |
//| info - array for the positions                                   |
//| tickets - array for the tickets                                  |
//+------------------------------------------------------------------+
void create_list(string &info[],int &tickets[])
  {
   //get the coordinates of the list activation button
   int x=ObjectGetInteger(0,"ActP_ord_button5",OBJPROP_XDISTANCE);
   int y=ObjectGetInteger(0, "ActP_ord_button5", OBJPROP_YDISTANCE)+ObjectGetInteger(0, "ActP_ord_button5", OBJPROP_YSIZE);
   //get colors
   color col=ObjectGetInteger(0,"ActP_ord_button5",OBJPROP_COLOR);
   color bgcol=ObjectGetInteger(0,"ActP_ord_button5",OBJPROP_BGCOLOR);
   //get window height
   int wnd_height=ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,wnd);
   int y_cnt=0;
   //proceed arrays
   for(int i=0;i<100;i++)
     {
      //break if end reached
      if(tickets[i]==-1) break;
      //calculate the list item coordinates
      int y_pos=y+y_cnt*20;
      //if the windiow limits are reachedl, start a new column
      if(y_pos+20>wnd_height) {x+=300; y_cnt=0;}
      y_pos=y+y_cnt*20;
      y_cnt++;
      string name="ActP_orders_list_"+IntegerToString(i)+" $"+IntegerToString(tickets[i]);
      //create element
      create_button(name,info[i],x,y_pos,300,20);
      //and set its properties
      ObjectSetInteger(0,name,OBJPROP_COLOR,col);
      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,0);
      ObjectSetInteger(0,name,OBJPROP_STATE,0);
      ObjectSetInteger(0,name,OBJPROP_FONTSIZE,8);
      ObjectSetInteger(0,name,OBJPROP_BGCOLOR,bgcol);
     }
  }

Ve son olarak, DeleteLists () işlevleri listenin öğelerini kaldırır:

//+------------------------------------------------------------------+
//| The function for the list deletion                               |
//+------------------------------------------------------------------+
void  DeleteLists(string IDstr)
  {
   //proceed all objects
   for(int i=ObjectsTotal(0);i>=0;i--)
     {
      string n=ObjectName(0,i);
      //delete lists
      if(StringFind(n,IDstr)>=0 && StringFind(n,"main")<0) ObjectDelete(0,n);
     }
  }

Yani etkinleştirme düğmesine tıkladığınızda bir liste oluşturulur. Listedeki herhangi bir öğeye her tıklandığında belirli bir işlem gerçekleşmesi gerektiği için, onu çalıştırmamız gerekir. Spesifik olarak: Bir talimatla çalışmak için bir arayüzün yüklenmesi ve bu arayüzün talimat/alım satım hakkında bilgilerle doldurulması. 

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
...
   // Event - click on a graphic object
   if(id==CHARTEVENT_OBJECT_CLICK)
   {
   ...
       //Click not on an item of order selection list
      if(StringFind(sparam, "ActP_orders_list_")<0)
      {
          //Remove it
         DeleteLists("ActP_orders_list_");
          //Set the activation button to "unpressed"
         ObjectSetInteger(0, "ActP_ord_button5", OBJPROP_STATE, 0);
          //redraw chart
         ChartRedraw();
      }     
       //Click on the order selection list item
      else
      {
          //Set a new name for the activation button
         ObjectSetString(0, "ActP_ord_button5", OBJPROP_TEXT, ObjectGetString(0, sparam, OBJPROP_TEXT));
          //Set the activation button to "unpressed"
         ObjectSetInteger(0, "ActP_ord_button5", OBJPROP_STATE, 0);
          //get ticket from the list item description
         int ticket=StringToInteger(StringSubstr(sparam, StringFind(sparam, "$")+1));
          //Load the interface
         SetScheme(ticket);
          //and delete the list
         DeleteLists("ActP_orders_list_");
          //chart redraw
         ChartRedraw();
      }
   ...   
   }
...
}

İş bu noktada karmaşıklaşıyor. Listenin boyutunu ve nesnelerinin adlarını önceden bilmediğimiz için, listenin öğesinin adına erişerek ondan bilgi almamız gerekecek. SetScheme() işlevi, bir alım satım işlemiyle veya bekleyen bir talimatla çalışmak için uygun arayüzü kuracaktır:

//+------------------------------------------------------------------+
//| The function sets the interface depending on type:               |
//| position or pending order                                        |
//| t - ticket                                                       |
//+------------------------------------------------------------------+
void SetScheme(int t)
  {
   //if position
   if(t==0)
     {
      //check for its presence
      if(PositionSelect(Symbol()))
        {
         //delete old scheme
         DeleteScheme("ActP",true);
         //and apply new
         ApplyScheme(6);
         //set position parameters
         SetPositionParams();
         //the objects are unavailable for the selection
         Objects_Selectable("ActP",false);
        }
     }
   //if order
   if(t>0)
     {
      //check for its presence
      if(OrderSelect(t))
        {
         //delete old scheme
         DeleteScheme("ActP",true);
         //and apply new
         ApplyScheme(7);
         //set order parameters
         SetOrderParams(t);
         //the objects are unavailable for the selection
         Objects_Selectable("ActP",false);
        }
     }
  }

SetPositionParams() ve SetOrderParams() işlevleri, yüklenen arayüzün gerekli özelliklerini yükler:

//+------------------------------------------------------------------+
//| Set position parameters for the objects                          |
//+------------------------------------------------------------------+
void SetPositionParams()
  {
   //if position is exists
   if(PositionSelect(Symbol()))
     {
      //get its parameters
      double pr=PositionGetDouble(POSITION_PRICE_OPEN);
      double lots=PositionGetDouble(POSITION_VOLUME);
      double sl=PositionGetDouble(POSITION_SL);
      double tp=PositionGetDouble(POSITION_TP);
      double mag=PositionGetInteger(POSITION_MAGIC);
      //and set new values to the objects
      ObjectSetString(0,"ActP_Pr_edit4",OBJPROP_TEXT,str_del_zero(DoubleToString(pr)));
      ObjectSetString(0,"ActP_lots_edit4",OBJPROP_TEXT,str_del_zero(DoubleToString(lots)));
      ObjectSetString(0,"ActP_SL_edit4",OBJPROP_TEXT,str_del_zero(DoubleToString(sl)));
      ObjectSetString(0,"ActP_TP_edit4",OBJPROP_TEXT,str_del_zero(DoubleToString(tp)));
      if(mag!=0) ObjectSetString(0,"ActP_mag_edit4",OBJPROP_TEXT,IntegerToString(mag));
      //redraw chart
      ChartRedraw();
     }
   //if there isn't position, show message 
   else MessageBox("There isn't open position for "+Symbol());
  }
//+------------------------------------------------------------------+
//| Set pending order parameters for the objects                     |
//| ticket - order ticket                                            |
//+------------------------------------------------------------------+
void SetOrderParams(int ticket)
  {
   //if order exists
   if(OrderSelect(ticket) && OrderGetString(ORDER_SYMBOL)==Symbol())
     {
      //get its parameters
      double pr=OrderGetDouble(ORDER_PRICE_OPEN);
      double lots=OrderGetDouble(ORDER_VOLUME_CURRENT);
      double sl=OrderGetDouble(ORDER_SL);
      double tp=OrderGetDouble(ORDER_TP);
      double mag=OrderGetInteger(ORDER_MAGIC);
      double lim=OrderGetDouble(ORDER_PRICE_STOPLIMIT);
      datetime expir=OrderGetInteger(ORDER_TIME_EXPIRATION);
      ENUM_ORDER_TYPE type=OrderGetInteger(ORDER_TYPE);
      ENUM_ORDER_TYPE_TIME expir_type=OrderGetInteger(ORDER_TYPE_TIME);
      
      //of order type is stoplimit, modify the interface
      if(type==ORDER_TYPE_BUY_STOP_LIMIT || type==ORDER_TYPE_SELL_STOP_LIMIT)
        {
         //set new value to the order price edit
         ObjectSetString(0,"ActP_limpr_edit3",OBJPROP_TEXT,DoubleToString(lim,_Digits));
         ObjectSetInteger(0,"ActP_limpr_edit3",OBJPROP_BGCOLOR,White);
         //set order price available for edit
         ObjectSetInteger(0,"ActP_limpr_edit3",OBJPROP_READONLY,false);
        }
      //if order type isn't stoplimit, modify the interface
      else
        {
         ObjectSetString(0,"ActP_limpr_edit3",OBJPROP_TEXT,"");
         ObjectSetInteger(0,"ActP_limpr_edit3",OBJPROP_BGCOLOR,LavenderBlush);
         ObjectSetInteger(0,"ActP_limpr_edit3",OBJPROP_READONLY,true);
        }

      //check expiration type
      //and set interface elements
      switch(expir_type)
        {
         case ORDER_TIME_GTC:
           {
            ObjectSetInteger(0,"ActP_exp1_radio3",OBJPROP_STATE,1);
            ObjectSetInteger(0,"ActP_exp2_radio3",OBJPROP_STATE,0);
            ObjectSetInteger(0,"ActP_exp3_radio3",OBJPROP_STATE,0);
            break;
           }
         case ORDER_TIME_DAY:
           {
            ObjectSetInteger(0,"ActP_exp1_radio3",OBJPROP_STATE,0);
            ObjectSetInteger(0,"ActP_exp2_radio3",OBJPROP_STATE,1);
            ObjectSetInteger(0,"ActP_exp3_radio3",OBJPROP_STATE,0);
            break;
           }
         case ORDER_TIME_SPECIFIED:
           {
            ObjectSetInteger(0,"ActP_exp1_radio3",OBJPROP_STATE,0);
            ObjectSetInteger(0,"ActP_exp2_radio3",OBJPROP_STATE,0);
            ObjectSetInteger(0,"ActP_exp3_radio3",OBJPROP_STATE,1);
            //in addition, set new value to the edit
            ObjectSetString(0,"ActP_exp_edit3",OBJPROP_TEXT,TimeToString(expir));
            break;
           }
        }
      //set new values for the objects
      ObjectSetString(0,"ActP_Pr_edit3",OBJPROP_TEXT,str_del_zero(DoubleToString(pr)));
      ObjectSetString(0,"ActP_lots_edit3",OBJPROP_TEXT,str_del_zero(DoubleToString(lots)));
      ObjectSetString(0,"ActP_SL_edit3",OBJPROP_TEXT,str_del_zero(DoubleToString(sl)));
      ObjectSetString(0,"ActP_TP_edit3",OBJPROP_TEXT,str_del_zero(DoubleToString(tp)));
      ObjectSetString(0,"ActP_ticket_edit3",OBJPROP_TEXT,IntegerToString(ticket));
      if(mag!=0) ObjectSetString(0,"ActP_mag_edit3",OBJPROP_TEXT,IntegerToString(mag));
      ChartRedraw();
     }
   //if there isn't such order, show message
   else MessageBox("There isn't an order with ticket "+IntegerToString(ticket)+" for "+Symbol());
  }

Ve son dokunuş - bu olay için CHARTEVENT_CLICK kullanarak grafiğe tıkladığınızda liste kaldırılmalıdır:

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
...
   //Event - is click on the chart
   if(id==CHARTEVENT_CLICK)
   {
       //delete all lists
      DeleteLists("ActP_orders_list_");
      DeleteLists("ActP_color_list_"); 
       //Set the activate buttons to the unpressed state
      ObjectSetInteger(0, "ActP_ord_button5", OBJPROP_STATE, 0);
      ObjectSetInteger(0, "ActP_col1_button6", OBJPROP_STATE, 0);
      ObjectSetInteger(0, "ActP_col2_button6", OBJPROP_STATE, 0);
      ObjectSetInteger(0, "ActP_col3_button6", OBJPROP_STATE, 0);
      ChartRedraw(); 
      return;
   }
...
}

Sonuç olarak, güzel bir açılır listemiz var:

Şekil 14 "Değiştir/Kapat" açılır liste paneli örneği

Şekil 14. "Değiştir /Kapat" açılır liste paneli örneği

Şimdi Ayarlar sekmesinde bir renk seçimi listesi oluşturmamız gerekiyor. 

Etkinleştirme düğmelerinin işleyicilerini göz önünde bulundurun:

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
...
   //Event - click on the chart
   if(id==CHARTEVENT_OBJECT_CLICK)
   {
   ...
       //Click on the button to activate the colors drop-down list
      if(sparam=="ActP_col1_button6")
      {
          //check state
         bool selected=ObjectGetInteger(0,sparam,OBJPROP_STATE);
          //the list is active
         if(selected)//the list is active
         {
             //creat list
            create_color_list(100, "ActP_col1_button6", 1);
             //Set the position of the remaining buttons to "unpressed"
            ObjectSetInteger(0, "ActP_col2_button6", OBJPROP_STATE, 0);
            ObjectSetInteger(0, "ActP_col3_button6", OBJPROP_STATE, 0);
             //delete other lists
            DeleteLists("ActP_color_list_2");
            DeleteLists("ActP_color_list_3");                 
         }
          //the list isn't selected
         else
         {
             //delete it
            DeleteLists("ActP_color_list_");
         }
          //redraw chart
         ChartRedraw();
          //finish the execution of function
         return;
      }
   ...   
   }
...
}

Burada talimat seçim listesiyle aynı yöntemi izliyoruz.

Liste oluşturma işlevi farklıdır:

//+------------------------------------------------------------------+
//| Function for creating the colors list                            |
//| y_max - maximal list widthа                                      |
//| ID - list ID                                                     |
//| num - interface number                                           |
//+------------------------------------------------------------------+
void create_color_list(int y_max,string ID,int num)
  {
  //Get the coordinates of the list activation button
   int x=ObjectGetInteger(0,ID,OBJPROP_XDISTANCE);
   int y=ObjectGetInteger(0, ID, OBJPROP_YDISTANCE)+ObjectGetInteger(0, ID, OBJPROP_YSIZE);
   //get color
   color col=ObjectGetInteger(0,ID,OBJPROP_COLOR);
   //and window width
   int wnd_height=ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,wnd);
   y_max+=y;
   int y_cnt=0;
   //We will go through the colors array
   for(int i=0;i<132;i++)
     {
      color bgcol=colors[i];
      //calculate list item coordinates
      int y_pos=y+y_cnt*20;
      //if we reached the boundaries of the window, start new column
      if(y_pos+20>wnd_height || y_pos+20>y_max) {x+=20; y_cnt=0;}
      y_pos=y+y_cnt*20;
      y_cnt++;
      //create new element
      string name="ActP_color_list_"+IntegerToString(num)+ID+IntegerToString(i);
      create_button(name,"",x,y_pos,20,20);
      //and set its properties
      ObjectSetInteger(0,name,OBJPROP_COLOR,col);
      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,0);
      ObjectSetInteger(0,name,OBJPROP_STATE,0);
      ObjectSetInteger(0,name,OBJPROP_BGCOLOR,bgcol);
     }
  }

Ayrıca liste öğesi için tıklama işlemini ele alalım:

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
...
   //Event - click on chart
   if(id==CHARTEVENT_OBJECT_CLICK)
   {
   ...
       //click isn't on the color list button
      if(StringFind(sparam, "ActP_color_list_1")<0)
      {
          //delete list
         DeleteLists("ActP_color_list_1");
          //set color list activation button to "unpressed"
         ObjectSetInteger(0, "ActP_col1_button6", OBJPROP_STATE, 0);
          //redraw chart
         ChartRedraw();
      }     
       //click on the color list
      else
      {
          //get color from the list
         color col=ObjectGetInteger(0, sparam, OBJPROP_BGCOLOR);
          //set it for all the buttons
         SetButtonsColor(col);
          //set button to unpressed
         ObjectSetInteger(0, "ActP_col1_button6", OBJPROP_STATE, 0);
          //delete list
         DeleteLists("ActP_color_list_1");
          //redraw chart
         ChartRedraw();
      }
   ...   
   }
...
}

SetButtonsColor() işlevi, düğmelerin rengini ayarlar:

//+------------------------------------------------------------------+
//| The function sets color for all buttons                          |
//| col - color                                                      |
//+------------------------------------------------------------------+
void SetButtonsColor(color col)
  {
   //We will go through all the objects
   for(int i=ObjectsTotal(0);i>=0;i--)
     {
      string n=ObjectName(0,i);
      //If the object belongs to the panel and its has a button type
      //set color
      if(StringFind(n,"ActP")>=0 && ObjectGetInteger(0,n,OBJPROP_TYPE)==OBJ_BUTTON) 
         ObjectSetInteger(0,n,OBJPROP_BGCOLOR,col); 
     }
   //set global variable
   GlobalVariableSet("ActP_buttons_color",col);
  }

Aşağıdaki sonuçlara bakalım:

Şekil 15 Düğmelerin renklerini ayarlama

Şekil 15. Düğmelerin renklerini ayarlama

Renk seçimi ve metin etiketleri listeleri benzerdir. Sonuç olarak, yalnızca birkaç tıklamayla paneli güzel bir şekilde renkli hale getirebiliriz:

Şekil 16 Panellerin, düğmelerin ve metnin renklerini değiştirme

Şekil 16 Panellerin, düğmelerin ve metnin renklerini değiştirme

Listelerle çalışmayı tamamladık. Giriş alanlarına geçelim.

5.5. Giriş Alanını Olayını İşleme

Giriş alanı, alandaki metnin düzenlenmesinin tamamlanmasının ardından meydana gelen bir CHARTEVENT_OBJECT_ENDEDIT olayı oluşturacaktır. Bu olayı işlememizin tek nedeni, giriş alanlarındaki fiyatlar ile ilgili fiyatlar için yardımcı çizgilerin ayarlanmasıdır.

Durma çizgisi örneğini ele alalım:

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
...
   //End edit event
   if(id==CHARTEVENT_OBJECT_ENDEDIT)//end edit event
   {
   ...
      //if edit field is SL field
      if(sparam=="ActP_SL_edit1")
      {
        //and auxiliary lines are enabled
         if(ObjectGetInteger(0,"ActP_DealLines_check1",OBJPROP_STATE)==1)
         {
            //get text from the field
            double sl_val=StringToDouble(ObjectGetString(0, "ActP_SL_edit1", OBJPROP_TEXT));
            //move lines at new position
            ObjectSetDouble(0, "ActP_SL_line1", OBJPROP_PRICE, sl_val);
         }
         //redraw chart
         ChartRedraw();
         //it ins't necessary to proceed the other objects, because the event from the one
         return;
      }
   ...   
   }
...
}

Diğer giriş alanları benzer şekilde işlenir.

5.6 Zamanlayıcı Olaylarını İşleme

Zamanlayıcı, yardımcı çizgileri izlemek için kullanılır. Bu şekilde, çizgileri hareket ettirdiğinizde bağlı oldukları fiyatların değerleri otomatik olarak giriş alanına taşınır. Zamanlayıcının her tick'iyle OnTimer() işlevi yürütülür.

Etkin "Piyasa" sekmesi ile Zararı Durdur ve Kar Al çizgilerinin takibini yerleştirme örneğini göz önünde bulundurun:

void OnTimer()// Timer handler
{
   //panel 1 is active
   if(ObjectGetInteger(0, "ActP_main_1", OBJPROP_STATE)==1)
   {  
      //if auxiliary lines are allowed
      if(ObjectGetInteger(0,"ActP_DealLines_check1",OBJPROP_STATE)==1)
      {
         //set new values to the edit fields
         double sl_pr=NormalizeDouble(ObjectGetDouble(0, "ActP_SL_line1", OBJPROP_PRICE), _Digits);
         //stop loss
         ObjectSetString(0, "ActP_SL_edit1", OBJPROP_TEXT, DoubleToString(sl_pr, _Digits));
         //take profit
         double tp_pr=NormalizeDouble(ObjectGetDouble(0, "ActP_TP_line1", OBJPROP_PRICE), _Digits);
         ObjectSetString(0, "ActP_TP_edit1", OBJPROP_TEXT, DoubleToString(tp_pr, _Digits));
      }   
   }
   ...
   //redraw chart
   ChartRedraw();
}
//+------------------------------------------------------------------+

Diğer çizgilerin takibi de benzer şekilde uygulanır.


6. Alım Satım İşlemleri Yapma

Bu noktada gerekli tüm giriş alanlarını, onay kutularını, satırları ve radyo düğmelerini tamamladık. Şimdi elimizdeki tüm verilere dayanarak biraz alım satım işlemi denemesi yapma zamanı.

6.1. Yatırım Açma

"Piyasadan" sekmesinde "Al" ve "Sat" düğmeleri yer alır. Tüm alanlar doğru doldurulursa, düğmelerden birine tıkladığımızda bir alım satım işleminin yapılması gerekir.

Bu düğmelerin işleyicilerine bakalım:

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
...
   //Event - click on the object on the chart
   if(id==CHARTEVENT_OBJECT_CLICK)
   {
   ...
       //click on the Buy button
      if(sparam=="ActP_buy_button1")
      {
          //check its state
         bool selected=ObjectGetInteger(0,sparam,OBJPROP_STATE);
          //if it "pressed"
         if(selected)
         {
             //try to perform a deal
            deal(ORDER_TYPE_BUY);
             //and set the button to the unpressed state
            ObjectSetInteger(0, sparam, OBJPROP_STATE, 0);
         }

          //redraw chart
         ChartRedraw();
          //and finish the function execution
         return;
      }
      //******************************************
       //the similar for the sell button
      if(sparam=="ActP_sell_button1")
      {
         bool selected=ObjectGetInteger(0,sparam,OBJPROP_STATE);
         if(selected)
         {
            deal(ORDER_TYPE_SELL);
            ObjectSetInteger(0, sparam, OBJPROP_STATE, 0);
         }
         ChartRedraw();
         return;
      }     
   ...   
   }
...
}

Gördüğünüz gibi deal() işlevi çalışıyor.

//+------------------------------------------------------------------+
//| Deal function                                                    |
//+------------------------------------------------------------------+
int deal(ENUM_ORDER_TYPE typ)
  {
   //get the data from the objects
   double SL=StringToDouble(ObjectGetString(0,"ActP_SL_edit1",OBJPROP_TEXT));
   double TP=StringToDouble(ObjectGetString(0, "ActP_TP_edit1", OBJPROP_TEXT));
   double lots=StringToDouble(ObjectGetString(0,"ActP_Lots_edit1",OBJPROP_TEXT));
   int mag=StringToInteger(ObjectGetString(0, "ActP_Magic_edit1", OBJPROP_TEXT));
   int dev=StringToInteger(ObjectGetString(0, "ActP_Dev_edit1", OBJPROP_TEXT));
   string comm=ObjectGetString(0,"ActP_Comm_edit1",OBJPROP_TEXT);
   ENUM_ORDER_TYPE_FILLING filling=ORDER_FILLING_FOK;
   if(ObjectGetInteger(0,"ActP_Exe2_radio1",OBJPROP_STATE)==1) filling=ORDER_FILLING_IOC;
   //prepare request
   MqlTradeRequest req;
   MqlTradeResult res;
   req.action=TRADE_ACTION_DEAL;
   req.symbol=Symbol();
   req.volume=lots;
   req.price=Ask;
   req.sl=NormalizeDouble(SL, Digits());
   req.tp=NormalizeDouble(TP, Digits());
   req.deviation=dev;
   req.type=typ;
   req.type_filling=filling;
   req.magic=mag;
   req.comment=comm;
   //send order
   OrderSend(req,res);
   //show message with the result
   MessageBox(RetcodeDescription(res.retcode),"Message");
   //return retcode
   return(res.retcode);
  }

Mucizevi bir durum yok. Önce nesnelerden gerekli bilgileri okuruz ve bunlara dayalı olarak bir alım satım talebi oluştururuz.

Şimdi işimizi kontrol edelim:

Şekil 17 Alım satım işlemleri - Alış işlemi uygulamasının sonucu

Şekil 17. Alım satım işlemleri - Alış işlemi uygulamasının sonucu

Gördüğünüz gibi, Alış işlemi başarıyla tamamlandı.

6.2. Bekleyen Bir Talimat Ayarlama

Bekleyen talimatların verilmesi için "Bekleyen" sekmesindeki "Al" ve "Sat" düğmeleri kullanılır.

İşleyicileri ele alalım:

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
...
   //Event - click on the chart object
   if(id==CHARTEVENT_OBJECT_CLICK)
   {
   ...
       //click on the pending order set button
      if(sparam=="ActP_buy_button2")
      {
         //check the button state
         bool selected=ObjectGetInteger(0,sparam,OBJPROP_STATE);
         //if it pressed
         if(selected)
         {
            ENUM_ORDER_TYPE typ; 
            //get the pending order from the edit
            double pr=NormalizeDouble(StringToDouble(ObjectGetString(0, "ActP_Pr_edit2", OBJPROP_TEXT)), Digits());
            //if it isn't stoplimit order
            if(ObjectGetInteger(0, "ActP_limit_check2", OBJPROP_STATE)==0)
            {
               //if the order price is below the current price, set limit order
               if(Ask>pr) typ=ORDER_TYPE_BUY_LIMIT; 
               //overwise - stop order
               else typ=ORDER_TYPE_BUY_STOP;
            }
              //if stoplimit order is specified
            else
            {
               //set operation type
               typ=ORDER_TYPE_BUY_STOP_LIMIT;
            }   
              //try to place order
            order(typ);
              //set button to the unpressed state
            ObjectSetInteger(0, sparam, OBJPROP_STATE, 0);
         }
          //redraw chart
         ChartRedraw();
          //and finish the execution of function
         return;
      }     
      //******************************************  

       //similar for the sell pending order
      if(sparam=="ActP_sell_button2")
      {
         bool selected=ObjectGetInteger(0,sparam,OBJPROP_STATE);
         if(selected)
         {
            ENUM_ORDER_TYPE typ;
            double pr=NormalizeDouble(StringToDouble(ObjectGetString(0, "ActP_Pr_edit2", OBJPROP_TEXT)), Digits());
            if(ObjectGetInteger(0, "ActP_limit_check2", OBJPROP_STATE)==0)
            {
               if(Bid<pr) typ=ORDER_TYPE_SELL_LIMIT;
               else typ=ORDER_TYPE_SELL_STOP;
            }
            else
            {
               typ=ORDER_TYPE_SELL_STOP_LIMIT;
            }   
            order(typ);
            ObjectSetInteger(0, sparam, OBJPROP_STATE, 0);
         }
         ChartRedraw();
         return;
      }        
   ...   
   }
...
}

Burada, mevcut piyasa fiyatının belirlenen fiyatla ilişkisine dayanarak gelecekteki talimatların türünü belirleriz, ardından order() işlevi talimatı belirler:

//+------------------------------------------------------------------+
//| The function places an order                                     |
//+------------------------------------------------------------------+
int order(ENUM_ORDER_TYPE typ)
  {
   //get the order details from the objects
   double pr=StringToDouble(ObjectGetString(0,"ActP_Pr_edit2",OBJPROP_TEXT));
   double stoplim=StringToDouble(ObjectGetString(0,"ActP_limpr_edit2",OBJPROP_TEXT));
   double SL=StringToDouble(ObjectGetString(0, "ActP_SL_edit2", OBJPROP_TEXT));
   double TP=StringToDouble(ObjectGetString(0, "ActP_TP_edit2", OBJPROP_TEXT));
   double lots=StringToDouble(ObjectGetString(0,"ActP_Lots_edit2",OBJPROP_TEXT));
   datetime expir=StringToTime(ObjectGetString(0,"ActP_exp_edit2",OBJPROP_TEXT));
   int mag=StringToInteger(ObjectGetString(0,"ActP_Magic_edit2",OBJPROP_TEXT));
   string comm=ObjectGetString(0,"ActP_Comm_edit2",OBJPROP_TEXT);
   ENUM_ORDER_TYPE_FILLING filling=ORDER_FILLING_FOK;
   if(ObjectGetInteger(0, "ActP_Exe2_radio2", OBJPROP_STATE)==1) filling=ORDER_FILLING_IOC;
   if(ObjectGetInteger(0, "ActP_Exe3_radio2", OBJPROP_STATE)==1) filling=ORDER_FILLING_RETURN;
   ENUM_ORDER_TYPE_TIME expir_type=ORDER_TIME_GTC;
   if(ObjectGetInteger(0, "ActP_exp2_radio2", OBJPROP_STATE)==1) expir_type=ORDER_TIME_DAY;
   if(ObjectGetInteger(0, "ActP_exp3_radio2", OBJPROP_STATE)==1) expir_type=ORDER_TIME_SPECIFIED;

   //prepare request
   MqlTradeRequest req;
   MqlTradeResult res; 
   req.action=TRADE_ACTION_PENDING;
   req.symbol=Symbol();
   req.volume=lots;
   req.price=NormalizeDouble(pr,Digits());
   req.stoplimit=NormalizeDouble(stoplim,Digits());
   req.sl=NormalizeDouble(SL, Digits());
   req.tp=NormalizeDouble(TP, Digits());
   req.type=typ;
   req.type_filling=filling;
   req.type_time=expir_type;
   req.expiration=expir;
   req.comment=comm;
   req.magic=mag;
   //place order
   OrderSend(req,res);
   //show message with the result
   MessageBox(RetcodeDescription(res.retcode),"Message");
   //return retcode
   return(res.retcode);
  }

Şimdi işimizi kontrol edelim:

Şekil 18 Alım satım işlemleri - Bekleyen talimat verme sonucu

Şekil 18. Alım satım işlemleri - Bekleyen talimat verme sonucu

Buy stoplimit başarıyla ayarlandı.

6.3. Pozisyon Değiştirme

"Değiştir/Kapat" sekmesindeki Düzenle düğmesi, seçilen pozisyonun değiştirilmesinden sorumludur:

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
...
   //Event - click on the graphic object on the chart
   if(id==CHARTEVENT_OBJECT_CLICK)
   {
   ...
       //click on the modify position button
      if(sparam=="ActP_mod_button4")
      {
          //check the button state
         bool selected=ObjectGetInteger(0,sparam,OBJPROP_STATE);
          //if it pressed
         if(selected)//if pressed
         {
            //modify position
            modify_pos();
            //delete the elements of the scheme
            DeleteScheme("ActP" ,true);
            //and reset it (update the interface)
            SetScheme(0);
            //set the button to the unpressed state
            ObjectSetInteger(0, sparam, OBJPROP_STATE, 0);
         }
          //redraw chart
         ChartRedraw();
          //finish the execution of function
         return;
      }     
   ...   
   }
...
}

Modify_pos() işlevi, değişiklikten doğrudan sorumludur:

//+------------------------------------------------------------------+
//| The function modifies the position parameters                    |
//+------------------------------------------------------------------+
int modify_pos()
  {
   if(!PositionSelect(Symbol())) MessageBox("There isn't open position for symbol "+Symbol(),"Message");
   //get the details from the edit objects
   double SL=StringToDouble(ObjectGetString(0,"ActP_SL_edit4",OBJPROP_TEXT));  
   double TP=StringToDouble(ObjectGetString(0, "ActP_TP_edit4", OBJPROP_TEXT));
   int dev=StringToInteger(ObjectGetString(0,"ActP_dev_edit4",OBJPROP_TEXT));
   //prepare request
   MqlTradeRequest req;
   MqlTradeResult res;  
   req.action=TRADE_ACTION_SLTP;
   req.symbol=Symbol();
   req.sl=NormalizeDouble(SL, _Digits);
   req.tp=NormalizeDouble(TP, _Digits);
   req.deviation=dev;
   //send request
   OrderSend(req,res);
   //show message with the result
   MessageBox(RetcodeDescription(res.retcode),"Message");
   //return retcode
   return(res.retcode);
  }

Sonuçlar:

Şekil 19 Alım satım işlemleri - Alım satımın özelliklerini değiştirmenin sonucu (TP ve SL kümesi)

Şekil 19. Alım satım işlemleri - Alım satımın özelliklerini değiştirmenin sonucu (TP ve SL)


Zararı Durdur ve Kar Al düzeyleri başarıyla değiştirildi.

6.4. Pozisyonu Kapatma

"Değiştir/Kapat" sekmesindeki Kapat düğmesi, pozisyonun kapatılmasından (muhtemelen kısmen) sorumludur:

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
...
   //Event - click on the chart object
   if(id==CHARTEVENT_OBJECT_CLICK)
   {
   ...
      //click on the close button
      if(sparam=="ActP_del_button4")
      {
         //check the button state
         bool selected=ObjectGetInteger(0,sparam,OBJPROP_STATE);
          //if pressed
         if(selected)
         {
            //try to close position
            int retcode=close_pos();
            //if successful
            if(retcode==10009)
            {
               //delete scheme elements
               DeleteScheme("ActP" ,true);
               //set the new text for the list activisation
               ObjectSetString(0, "ActP_ord_button5", OBJPROP_TEXT, "Select order -->");
            }
            //set button state to unpressed
            ObjectSetInteger(0, sparam, OBJPROP_STATE, 0);
         }
          //redraw chart
         ChartRedraw();
          //finish the execution of function
         return;
      }     
   ...   
   }
...
}

close_pos() işlevi kapatma işleminden sorumludur:

//+------------------------------------------------------------------+
//| Closes the position                                              |
//+------------------------------------------------------------------+
int close_pos()
  {
   if(!PositionSelect(Symbol())) MessageBox("There isn't open position for symbol "+Symbol(),"Message");
   //get the position details from the objects
   double lots=StringToDouble(ObjectGetString(0,"ActP_lots_edit4",OBJPROP_TEXT));
   if(lots>PositionGetDouble(POSITION_VOLUME)) lots=PositionGetDouble(POSITION_VOLUME);
   int dev=StringToInteger(ObjectGetString(0, "ActP_dev_edit4", OBJPROP_TEXT));
   int mag=StringToInteger(ObjectGetString(0, "ActP_mag_edit4", OBJPROP_TEXT));

   //prepare request
   MqlTradeRequest req;
   MqlTradeResult res;

   //the opposite deal is dependent on position type
   if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
     {
      req.price=Bid;
      req.type=ORDER_TYPE_SELL;
     }
   else
     {
      req.price=Ask;
      req.type=ORDER_TYPE_BUY;
     }

   req.action=TRADE_ACTION_DEAL;
   req.symbol=Symbol();
   req.volume=lots;
   req.sl=0;
   req.tp=0;
   req.deviation=dev;
   req.type_filling=ORDER_FILLING_FOK;
   req.magic=mag;
   //send request
   OrderSend(req,res);
   //show message with the result
   MessageBox(RetcodeDescription(res.retcode),"Message");
   //return retcode
   return(res.retcode);
  }

Sonuç - seçilen işlemden üç adet 1,5 lot kapatıldı:

Şekil 20 Alım satım işlemi - kısmi pozisyon kapatma

Şekil 20. Alım satım işlemi - kısmi pozisyon kapatma

6.5. Bekleyen Bir Talimatı Değiştirme

"Değiştirme/kapatma" sekmesindeki Düzenle düğmesi, seçilen talimatın değiştirilmesinden sorumludur:

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
...
   //Event - click on the chart graphic object
   if(id==CHARTEVENT_OBJECT_CLICK)
   {
   ...
      //click on the order modify button
      if(sparam=="ActP_mod_button3")
      {
         bool selected=ObjectGetInteger(0,sparam,OBJPROP_STATE);
         if(selected)
         {     
            //get the order ticket from the edit
            string button_name=ObjectGetString(0, "ActP_ord_button5", OBJPROP_TEXT);
            long ticket=StringToInteger(StringSubstr(button_name, 1, StringFind(button_name, " ")-1));
            //modifying an order
            modify_order(ticket);
            //update interface
            DeleteScheme("ActP" ,true);
            SetScheme(ticket);
            //set button to unpressed state
            ObjectSetInteger(0, sparam, OBJPROP_STATE, 0);
         }
          //redraw chart
         ChartRedraw();
          //and finish the execution of function
         return;
      }     
   ...   
   }
...
}

Modify_order () işlevi değişiklikten sorumludur:

//+------------------------------------------------------------------+
//| The function modifies an order                                   |
//| ticket - order ticket                                            |
//+------------------------------------------------------------------+
int modify_order(int ticket)
  {
   //get the order details from the corresponding chart objects
   double pr=StringToDouble(ObjectGetString(0,"ActP_Pr_edit3",OBJPROP_TEXT)); 
   double stoplim=StringToDouble(ObjectGetString(0,"ActP_limpr_edit3",OBJPROP_TEXT));
   double SL=StringToDouble(ObjectGetString(0, "ActP_SL_edit3", OBJPROP_TEXT));
   double TP=StringToDouble(ObjectGetString(0, "ActP_TP_edit3", OBJPROP_TEXT));
   double lots=StringToDouble(ObjectGetString(0,"ActP_Lots_edit3",OBJPROP_TEXT));
   datetime expir=StringToTime(ObjectGetString(0,"ActP_exp_edit3",OBJPROP_TEXT));
   ENUM_ORDER_TYPE_TIME expir_type=ORDER_TIME_GTC;
   if(ObjectGetInteger(0, "ActP_exp2_radio3", OBJPROP_STATE)==1) expir_type=ORDER_TIME_DAY;
   if(ObjectGetInteger(0, "ActP_exp3_radio3", OBJPROP_STATE)==1) expir_type=ORDER_TIME_SPECIFIED;

   //prepare request to modify
   MqlTradeRequest req;
   MqlTradeResult res;
   req.action=TRADE_ACTION_MODIFY;
   req.order=ticket;
   req.volume=lots;
   req.price=NormalizeDouble(pr,Digits());
   req.stoplimit=NormalizeDouble(stoplim,Digits());
   req.sl=NormalizeDouble(SL, Digits());
   req.tp=NormalizeDouble(TP, Digits());
   req.type_time=expir_type;
   req.expiration=expir;
   //send request
   OrderSend(req,res);
   //show message with the result
   MessageBox(RetcodeDescription(res.retcode),"Message");
   //return retcode
   return(res.retcode);
  }

Sonuca bakalım - Bir talimat başarıyla değiştirildi:

Şekil 21 Bekleyen talimatı değiştirme

Şekil 21. Bekleyen talimatı değiştirme

6.6. Bekleyen Talimatı Silme

"Değiştirme/Kapatma" sekmesindeki Sil düğmesi, seçilen talimatın silinmesinden sorumludur:

void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam)
{
...
   //Event - click on the graphic object on the chart
   if(id==CHARTEVENT_OBJECT_CLICK)
   {
   ...
       //click on the order delete button
      if(sparam=="ActP_del_button3")
      {
         //check the button state
         bool selected=ObjectGetInteger(0,sparam,OBJPROP_STATE);
          //if pressed
         if(selected)
         {
            //get the ticket from the list
            string button_name=ObjectGetString(0, "ActP_ord_button5", OBJPROP_TEXT);
            long ticket=StringToInteger(StringSubstr(button_name, 1, StringFind(button_name, " ")-1));
            //try to delete order
            int retcode=del_order(ticket);
            //if successful
            if(retcode==10009)
            {
               //delete all objects of the scheme
               DeleteScheme("ActP" ,true);
               //set new text for the list activation button
               ObjectSetString(0, "ActP_ord_button5", OBJPROP_TEXT, "Select an order -->");
            }
             //set button state to unpressed
            ObjectSetInteger(0, sparam, OBJPROP_STATE, 0);
         }
          //redraw chart
         ChartRedraw();
          //and finish the execution of function
         return;
      }     
   ...   
   }
...
}

Del_order() işlevi, talimatların kaldırılmasından sorumludur:

//+------------------------------------------------------------------+
//| The function for pending order deletion                          |
//| ticket - order ticket                                            |
//+------------------------------------------------------------------+
int del_order(int ticket)
  {
   //prepare request for deletion
   MqlTradeRequest req;
   MqlTradeResult res;
   req.action=TRADE_ACTION_REMOVE;
   req.order=ticket;
   //send request
   OrderSend(req,res);
   //show message with the result
   MessageBox(RetcodeDescription(res.retcode),"Message");
   //return retcode
   return(res.retcode);
  }

Sonuca bakalım - Talimat kaldırıldı.

Şekil 22 Alım Satım İşlemi - Bekleyen bir talimatı kaldırma

Şek. 22 Alım satım işlemleri - Bekleyen bir talimatı kaldırma


Sonuç

Son olarak panelin tüm işlevleri test edilmiş olup bunlar başarılı bir şekilde çalışmaktadır.

Umarım bu makaleyi okuyarak edindiğiniz bilgiler, piyasada çalışmak için eşsiz yardımcılar işlevi görecek aktif kontrol panellerinin geliştirilmesinde size yardımcı olacaktır. 

Paneli kullanmaya başlamak için arşivi terminal ile bir klasöre açmanız, ardından grafiğe AP göstergesini uygulamanız gerekir; ancak o zaman Aktif Panel Expert Advisor'ı başlatabilirsiniz.


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

Ekli dosyalar |
Expert Advisor'ın MQL5'te ICQ ile Bağlantısı Expert Advisor'ın MQL5'te ICQ ile Bağlantısı
Bu makalede, Expert Advisor ve ICQ kullanıcıları arasındaki bilgi alışverişi yöntemi açıklanmakta olup birkaç örnek sunulmaktadır. Sunulan materyal, bir istemci terminalinden, bir ICQ istemcisi aracılığıyla cep telefonlarına veya PDA'larına alım satım bilgilerini uzaktan almak isteyen kişiler için ilgi çekici olacaktır.
Alım Satım Raporları ve SMS Bildirimi Oluşturma ve Yayınlama Alım Satım Raporları ve SMS Bildirimi Oluşturma ve Yayınlama
Yatırımcıların her zaman alım satım terminalinde saatlerce oturma yeteneği ve arzusu yoktur. Özellikle, alım satım sistemi az çok resmileştirilmişse ve bazı piyasa durumlarını otomatik olarak tanımlayabiliyorsa. Bu makalede, alım satım sonuçları raporunun (Expert Advisor, Gösterge veya Script Dosyası kullanılarak) HTML dosyası olarak nasıl oluşturulacağı ve FTP yoluyla WWW-sunucusuna nasıl yükleneceği açıklanmaktadır. Ayrıca alım satım etkinliklerine ilişkin bildirimlerin cep telefonuna SMS olarak gönderilmesini de değerlendireceğiz.
MQL5'te "Yılan" Oyunu Oluşturma MQL5'te "Yılan" Oyunu Oluşturma
Bu makalede, bir "Yılan" oyun programlama örneği açıklanmaktadır. MQL5'te oyun programlama, öncelikle olay işleme özellikleri nedeniyle mümkün hale geldi. Nesne yönelimli programlama bu süreci büyük ölçüde basitleştirir. Bu makalede olay işleme özelliklerini, Standart MQL5 Kitaplık sınıflarının kullanım örneklerini ve periyodik işlev çağrılarının detaylarını öğreneceksiniz.
Farklı Kıtalardaki Saat Dilimi Farklılıklarına Dayalı Bir Alım Satım Stratejisi Örneği Farklı Kıtalardaki Saat Dilimi Farklılıklarına Dayalı Bir Alım Satım Stratejisi Örneği
İnternette gezinirken, size çeşitli önerilerde bulunacak birçok strateji bulmak kolaydır. İç yüzünü bilen bir kişinin yaklaşımını ele alalım ve farklı kıtalardaki saat dilimlerindeki farklılıklara dayalı olarak strateji oluşturma sürecini inceleyelim.