English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
MQL5'te 20 Alım Satım Sinyali

MQL5'te 20 Alım Satım Sinyali

MetaTrader 5Örnekler | 9 Aralık 2021, 11:04
163 0
Sergey Gritsay
Sergey Gritsay

Giriş

Yatırımcılar, fiyat davranışında düzenlilikler bulmaya çalışırlar, alışa veya satışa uygun bir anı belirlemek için iyi bir şansa sahip olacakları kurallar oluşturmaya çalışırlar. Tam otomatik bir sistem oluşturmak için bu tür anların, yani alım satım sinyallerinin geleceği hakkında nasıl bilgi vereceğinizi öğrenmeniz gerekir.

Sinyaller, yatırımcılara bir pozisyona girmenin potansiyel noktaları hakkında bilgi verir ancak bunların hepsinin uygulanması zorunlu değildir. Ek kriterler sinyallerin çoğunu bile filtreleyebilir, ancak bizim için önemli değildir. Makalenin konusu, MQL5'te en popüler alım satım sinyallerinin nasıl programlanacağıdır.


1. Hangi Sinyalleri Biliyoruz?

Piyasaya girme anlarını belirlemenin tüm yöntemleri birkaç türe ayrılabilir:

  • hareketli ortalamaların kesişimi
  • bir aralığın kırılımı
  • stokastik oranlar temelinde aşırı alış/aşırı satış bölgesinden çıkış
  • bir kanalın sınırlarından sıçrama
  • bir kanalın sınırlarının kırılımı
  • trend değişikliği


2. Nasıl Daha İyi Kodlanır?

Kod yazmanın birçok yolu vardır; OnStart(), OnTick() ve diğer fonksiyonlar içinde yazılabilir. Bunlarla ilgili daha ayrıntılı bilgiyi bu web sitesindeki belgelerde veya MetaEditor'da gömülü olan kullanım kılavuzunda bulabilirsiniz; ancak bu yöntem etkili değildir ve bazen kodun aynı kısımlarını birkaç kez yazmanız gerekir. Bu şekilde başka bir yol izleyeceğiz - programımızın kodunun herhangi bir bölümünden çağrılabilecek özel fonksiyonları kullanacağız.

Oluşturulan fonksiyonların kullanım kolaylığı için bunları ayrı bir grupta harici bir içerik dosyası olarak birleştirelim ve SignalTrade olarak adlandıralım; ...\MQL5\Include dizininde saklanacaktır. Bu modülün herhangi bir programa kolayca bağlanmasını sağlayacaktır. 

Tüm sinyaller farklı görünse de birçok ortak noktaları olabilir. Sinyalleri üreten bir fonksiyondan alınabilecek üç değişken vardır:

  • alma sinyali
  • satma sinyali
  • sinyal yok

Şimdi bu sinyallere karşılık gelen bir numaralandırma oluşturalım.

  •  1 - alma sinyali
  • -1 - satma sinyali
  •  0 - sinyal yok

Sinyal döndüren fonksiyonun bir prototipini yazalım. Fonksiyonumuzu, bir veya daha fazla işlemin gerçekleştirileceği birkaç bölüme ayırın. Veri depolamak için gerekli olan değişkenler, fonksiyonun başlangıcında bildirilir ve başlatılır. Oluşturulan göstergeden gerekli bilgilerin yüklenmesi ve kontrolü ayrıca yapılacaktır. Verilerle çalışmanın ve bir bütün olarak programın öngörülemeyen sonuçlarından kaçınmak için bilgilerin kontrol edilmesi esastır. 

Bilgi yüklenip kontrol edildikten sonra, bir sinyal oluşturma adımına gidin. Bir sinyal oluşur oluşmaz fonksiyondan çıkın ve elde edilen sinyali yukarıda belirtilen değerlerden biri olarak ona döndürün.

int TradeSignal()
  {
   //--- zero means absence of signal
   int sig=0;
   
   //--- check the handles of indicators

   //--- if all the handles are invalid, create them

   //--- if the handles are valid, copy the values from indicators

   //--- check the copied data

   //--- in case of an error of copying, exit from the function

   //--- perform the indexation of the array as a timeseries

   //--- in case of an indexation error, exit from the function

   //--- check conditions and set the value for sig
 
   //--- return the trade signal
   return(sig);
  }


3. 20 Alım Satım Sinyali Örneği

Alım satım sinyallerini almak için farklı göstergeler kullanacağız. MQL5'te göstergeler özel fonksiyonlar kullanılarak çağrılır, örneğin iMA, iAC, iMACD, iIchimoku vb.; istemci terminalinin genel önbelleğinde ilgili teknik göstergenin bir kopyasını oluştururlar. Aynı parametrelere sahip bir gösterge kopyası zaten mevcutsa yeni kopya oluşturulmaz ve mevcut kopyaya olan bağlantıların sayacı artar.

Bu fonksiyonlar, ilgili gösterge kopyasının tanıtıcı değerini verir. Bu tanıtıcı değer kullanılarak, ilişkili göstergeye dair veriler alınabilir. İlişkili tampon verisi (teknik göstergeler, hesaplanan verileri gösterge türüne bağlı olarak, sayısı 1 ila 5 arasında değişebilen dahili tamponlarda barındırır) CopyBuffer() fonksiyonu kullanılarak bir MQL5 programına kopyalanabilir.

Bir göstergenin verilerini, oluşturulduktan hemen sonra kullanmak imkansızdır, çünkü göstergenin değerlerini hesaplamak için biraz zamana ihtiyaç vardır; bu yüzden en iyi yol, tanıtıcı değerleri OnInit() içinde oluşturmaktır. iCustom() fonksiyonu, karşılık gelen özel göstergeyi oluşturur ve oluşturma başarılı olursa, göstergenin tanıtıcı değerini verir. Özel göstergeler 512 adede kadar gösterge tamponu içerebilirler. Tamponların içerikleri, CopyBuffer() fonksiyonu ve elde edilen tanıtıcı değer kullanılarak edinilebilir.

Her sinyal için TradeSignal() prototipimize göre bir fonksiyon oluşturalım ve bunları aşağıdaki sırayla numaralandıralım: TradeSignal_01() - TradeSignal_20(). Hareketli ortalamaların kesişimine dayalı bir sinyal örneğini kullanarak bir sinyal oluşturma fonksiyonunun yapısına ayrıntılı bir göz atalım; sonra diğer sinyaller için fonksiyonları benzer şekilde yazacağız.

3.1. Hareketli Ortalamaların Kesişimi

Şekil 1. İki hareketli ortalamanın kesişimi

Şekil 1. İki hareketli ortalamanın kesişimi

TradeSignal_01() fonksiyonunu kullanarak, iki Hareketli Ortalamanın (МА) kesişimi hakkında bir sinyal alacağız: 8 dönemli hızlı olan ve 16 dönemli yavaş olan.

Fonksiyonumuzda sadece kesişim gerçeğini düzelteceğiz ve karşılık gelen sinyalin değerini fonksiyona döndüreceğiz. Kurallarımıza ve prototipimize göre fonksiyon şöyle görünecek:

int TradeSignal_01()
  {
//--- zero means that there is no signal
   int sig=0;

//--- check the handles of indicators
   if(h_ma1==INVALID_HANDLE)//--- if the handle is invalid
     {
      //--- create is again                                                      
      h_ma1=iMA(Symbol(),Period(),8,0,MODE_SMA,PRICE_CLOSE);
      //--- exit from the function
      return(0);
     }
   else //--- if the handle is valid
     {
      //--- copy value of the indicator to the array
      if(CopyBuffer(h_ma1,0,0,3,ma1_buffer)<3) //--- if the array of data is less than required
         //--- exit from the function
         return(0);
      //--- set the indexation in the array as in a timeseries                                   
      if(!ArraySetAsSeries(ma1_buffer,true))
         //--- in case of an indexation error, exit from the function
         return(0);
     }

   if(h_ma2==INVALID_HANDLE)//--- if the handle is invalid
     {
      //--- create it again                                                      
      h_ma2=iMA(Symbol(),Period(),16,0,MODE_SMA,PRICE_CLOSE);
      //--- exit from the function
      return(0);
     }
   else //--- if the handle is valid 
     {
      //--- copy values of the indicator to the array
      if(CopyBuffer(h_ma2,0,0,2,ma2_buffer)<2) //--- if there is less data than required
         //--- exit from the function
         return(0);
      //--- set the indexation in the array as in a timeseries                                   
      if(!ArraySetAsSeries(ma1_buffer,true))
         //--- in case of an indexation error, exit from the function
         return(0);
     }

//--- check the condition and set a value for the sig
   if(ma1_buffer[2]<ma2_buffer[1] && ma1_buffer[1]>ma2_buffer[1])
      sig=1;
   else if(ma1_buffer[2]>ma2_buffer[1] && ma1_buffer[1]<ma2_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

Şimdi kodun her bölümüne daha ayrıntılı bir göz atalım. Fonksiyonun başında, sinyal tipini saklayacak ve sinyal yokluğu anlamına gelen sıfır ile başlatacak bir yerel değişken tanımlıyoruz.

int sig=0;

Ayrıca, tanıtıcı değerin geçerliliğini kontrol ediyoruz; tanıtıcı değer geçersizse onu oluştururuz ve fonksiyondan çıkarız, çünkü göstergenin hesaplanması biraz zaman alır. Gösterge tamponundan veri kopyalama hatasını önlemek için uygulanır.

   if(h_ma1==INVALID_HANDLE)//--- if the handle is invalid
     {
      //--- create it again                                                      
      h_ma1=iMA(Symbol(),Period(),8,0,MODE_SMA,PRICE_CLOSE);
      //--- exit from the function
      return(0);
     }

Tanıtıcı değer geçerliyse verileri diziye kopyalayın. Durumu analiz etmek için hızlı MA'nın son üç çubuğunun ve yavaş MA'nın iki çubuğunun verilerini kopyalamak yeterlidir. Bu amaç için aşağıdaki fonksiyonu kullanın:

int  CopyBuffer(
   int       indicator_handle,     // handle of an indicator
   int       buffer_num,           // number of buffer of an indicator
   int       start_pos,            // where to start from 
   int       count,                // amount to be copied
   double    buffer[]              // an array to copy data to
   );

Bunları kontrol edin: gerekenden daha az veri varsa bu bir kopyalama hatası olduğu anlamına gelir ve verilerin saklanması gereken diziye daha fazla başvuru yapılması bir hataya yol açacaktır. Bundan kaçınmak için fonksiyondan çıkıyoruz. Ayrıca dizideki indislemeyi bir zaman serisinde olduğu gibi ayarlamamız gerekiyor; aşağıdaki fonksiyon bunun için tasarlanmıştır:

bool  ArraySetAsSeries(
   void  array[],     // array by a link
   bool  set          // true means that the indexation order is reversed
   );

Dizinin indislenmesi sırasında bir hata oluştuysa fonksiyondan çıkın, aksi halde hatalı sonuçlar alabiliriz.

else //--- if the handle is valid 
     {
      //--- copy values of the indicator to the array
      if(CopyBuffer(h_ma1,0,0,3,ma1_buffer)<3) //--- if there is less data than required
         //--- exit from the function
         return(0);
      //--- set the indexation in the array like in a timeseries                                   
      if(!ArraySetAsSeries(ma1_buffer,true))
         //--- in case of an indexation error, exit from the function
         return(0);
     }

Şimdi, göstergeler oluşturulduğuna ve gerekli tüm bilgiler elde edildiğine göre ana aşama olan bir sinyal oluşturmaya geçelim.

Geçerli çubukta sinyalin titremesini ortadan kaldırmak için yalnızca kapalı 1. ve 2. çubukları analiz edin.

Satın alma sinyalini oluşturun. Bu amaçla, 2. çubuktaki hızlı MA'nın değerini alın ve 1. çubuktaki yavaş MA'nın değeriyle karşılaştırın; ardından 1. çubuktaki hızlı MA'nın değerini 1. çubuktaki yavaş MA'nın değeriyle karşılaştırın. 2. çubuktaki hızlı MA'nın değeri 1. çubuktaki yavaş MA'nın değerinden küçükse ve 1. çubuktaki hızlı MA'nın değeri 1. çubuktaki yavaş MA'nın değerinden büyükse, hızlı MA'nın yavaş olanı yukarı doğru geçtiği anlamına gelir; bu bizim satın alma sinyalimizdir. Koşulumuz doğruysa, sig değişkenine 1 yazın.

Satış sinyali de benzer şekilde oluşturulur. 2. çubuktaki hızlı MA, 1. çubuktaki yavaş MA'dan büyükse ve 1. çubuktaki hızlı MA, 1. çubuktaki yavaş MA'dan küçükse bu, hızlı MA’nın yavaş MA'yı yukarıdan aşağıya doğru geçtiği anlamına gelir. Koşulumuz doğruysa sig değişkenine -1 değerini yazın. Her iki koşul da yanlış ise sinyal yok demektir bu yüzden sig değişkenine 0 değerini yazıyoruz. Şimdi sinyaller oluşturulduğuna göre elde edilen sinyal türünü TradeSignal_01() fonksiyonumuza döndürün

//--- check the condition and set a value for the sig
   if(ma1_buffer[2]<ma2_buffer[1] && ma1_buffer[1]>ma2_buffer[1])
      sig=1;
   else if(ma1_buffer[2]>ma2_buffer[1] && ma1_buffer[1]<ma2_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);

3.2. MACD Ana ve Sinyal Çizgisinin Kesişmesi

Şekil 2. MACD göstergesinin ana ve sinyal çizgisinin kesişimi

TradeSignal_02() fonksiyonunda, sinyalin ve MACD'nin ana çizgisinin kesişimiyle ilgili sinyali alacağız. Sinyal çizgisi ana çizgiyi yukarıdan aşağıya doğru geçerse bu, satın alma sinyalidir. Sinyal çizgisi ana çizgiyi aşağıdan yukarıya doğru geçerse bu, satış sinyalidir. Diğer durumlar sinyal yokluğu olarak kabul edilecektir.

int TradeSignal_02()
  {
   int sig=0;

   if(h_macd==INVALID_HANDLE)
     {
      h_macd=iMACD(Symbol(),Period(),12,26,9,PRICE_CLOSE);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_macd,0,0,2,macd1_buffer)<2)
         return(0);
      if(CopyBuffer(h_macd,1,0,3,macd2_buffer)<3)
         return(0);
      if(!ArraySetAsSeries(macd1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(macd2_buffer,true))
         return(0);
     }

//--- check the condition and set a value for sig
   if(macd2_buffer[2]>macd1_buffer[1] && macd2_buffer[1]<macd1_buffer[1])
      sig=1;
   else if(macd2_buffer[2]<macd1_buffer[1] && macd2_buffer[1]>macd1_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.3. Fiyat Kanal Aralığında Kırılım

Şekil 3. Fiyat Kanalının alt ve üst sınırlarının kırılımı

TradeSignal_03() fonksiyonunda, Fiyat Kanalının üst veya alt sınırlarının bir kırılımıyla ilgili sinyali alacağız.

Fiyat, Fiyat Kanalının üst sınırını delerse ve fiyat bu sınırın üzerinde sabitlenirse bu, satın alma sinyalidir. Fiyat, Fiyat Kanalının alt sınırını delerse ve fiyat bu sınırın altında sabitlenirse bu, satış sinyalidir. Diğer durumlar sinyal yokluğu olarak kabul edilir.

Önceki iki fonksiyondan farklı olarak, burada kapanış fiyatlarını saklamak için bir diziye ihtiyacımız var. Bunları almak için aşağıdaki fonksiyonu kullanın:

int  CopyClose(
   string           symbol_name,       // symbol name
   ENUM_TIMEFRAMES  timeframe,          // period
   int              start_pos,         // where to start from 
   int              count,             // amount to be copied
   double           close_array[]      // array for copying close prices to
   );
int TradeSignal_03()
  {
   int sig=0;

   if(h_pc==INVALID_HANDLE)
     {
      h_pc=iCustom(Symbol(),Period(),"Price Channel",22);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_pc,0,0,3,pc1_buffer)<3)
         return(0);
      if(CopyBuffer(h_pc,1,0,3,pc2_buffer)<3)
         return(0);
      if(CopyClose(Symbol(),Period(),0,2,Close)<2)
         return(0);
      if(!ArraySetAsSeries(pc1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(pc2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the conditions and set a value for sig
   if(Close[1]>pc1_buffer[2])
      sig=1;
   else if(Close[1]<pc2_buffer[2])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.4. ADX Uyarlanabilir Kanal Aralığının Kırılımı

Şekil 4. ADX uyarlamalı kanalın üst ve alt sınırlarının kırılımı.

TradeSignal_04() fonksiyonunu kullanarak, ADX uyarlanabilir kanalının üst veya alt sınırlarındaki bir kırılım hakkında sinyal alacağız.

Fiyat, adaptif kanal ADX'in üst sınırını delerse ve kapanış fiyatı bu sınırın üzerinde sabitlenirse bu, satın alma sinyalidir. Fiyat, Fiyat Kanalının alt sınırını delerse ve kapanış fiyatı bu sınırın altında sabitlenirse bu, satış sinyalidir. Diğer durumlar sinyal yokluğu olarak kabul edilir.

int TradeSignal_04()
  {
   int sig=0;

   if(h_acadx==INVALID_HANDLE)
     {
      h_acadx=iCustom(Symbol(),Period(),"AdaptiveChannelADX",14);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_acadx,0,0,2,acadx1_buffer)<2)
         return(0);
      if(CopyBuffer(h_acadx,1,0,2,acadx2_buffer)<2)
         return(0);
      if(CopyClose(Symbol(),Period(),0,2,Close)<2)
         return(0);
      if(!ArraySetAsSeries(acadx1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(acadx2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the condition and set a value for the sig
   if(Close[1]>acadx1_buffer[1])
      sig=1;
   else if(Close[1]<acadx2_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.5. Stokastiğin Aşırı Alış/Aşırı Satış Bölgelerinden Çıkış

Şekil 5. Stokastik tarafından aşırı alış ve aşırı satış seviyelerinin geçişi.

TradeSignal_05() öğesini kullanarak, stokastikten aşırı alış/aşırı satış bölgelerinden çıkış sinyalini alacağız; bu bölgelerin seviyeleri 80 ve 20 değerlerine sahip seviyeler olacaktır.

Osilatör (%K veya %D) belirli bir seviyenin altına düşüp (genellikle 20'dir) daha sonra yükseldiğinde satın alırız. Osilatör belirli bir seviyenin üzerine çıkıp (genellikle 80'dir) daha sonra altına düştüğünde satıyoruz.

int TradeSignal_05()
  {
   int sig=0;

   if(h_stoh==INVALID_HANDLE)
     {
      h_stoh=iStochastic(Symbol(),Period(),5,3,3,MODE_SMA,STO_LOWHIGH);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_stoh,0,0,3,stoh_buffer)<3)
         return(0);

      if(!ArraySetAsSeries(stoh_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(stoh_buffer[2]<20 && stoh_buffer[1]>20)
      sig=1;
   else if(stoh_buffer[2]>80 && stoh_buffer[1]<80)
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.6. RSI’nin Aşırı Alış/Aşırı Satış Bölgelerinden Çıkış

Şekil 6. RSI göstergesi ile aşırı alış ve aşırı satış seviyelerinin geçişi

TradeSignal_06() fonksiyonunu kullanarak, aşırı alış/aşırı satış bölgelerinden RSI göstergesinin çıkmasıyla ilgili sinyali alacağız; bu bölgeler için seviyeler 70 ve 30 değerlerine sahip seviyelerdir.

RSI belirli bir seviyenin altına düştüğünde (genellikle 30'dur) ve daha sonra o seviyenin üzerine çıktığında satın alırız. RSI belirli bir seviyenin üzerine çıkıp (genellikle 70'tir) daha sonra o seviyenin altına düştüğünde satarız.

int TradeSignal_06()
  {
   int sig=0;

   if(h_rsi==INVALID_HANDLE)
     {
      h_rsi=iRSI(Symbol(),Period(),14,PRICE_CLOSE);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_rsi,0,0,3,rsi_buffer)<3)
         return(0);

      if(!ArraySetAsSeries(rsi_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(rsi_buffer[2]<30 && rsi_buffer[1]>30)
      sig=1;
   else if(rsi_buffer[2]>70 && rsi_buffer[1]<70)
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
 
3.7. CCI’nin Aşırı Alış/Aşırı Satış Bölgelerinden Çıkış

Şekil 7. CCI göstergesi ile aşırı alış ve aşırı satış seviyelerinin aşılması

TradeSignal_07() öğesini kullanarak, aşırı alış/aşırı satış bölgelerinden CCI göstergesinin çıkışına ilişkin sinyali alacağız; bu bölgeler için seviyeler 100 ve -100 değerlerine sahip seviyelerdir.

CCI -100 seviyesinin altına düşüp daha sonra bu seviyenin üzerine çıktığında satın alırız. CCI 100 seviyesinin üzerine çıkıp daha sonra bu seviyenin altına düştüğünde satarız.

int TradeSignal_07()
  {
   int sig=0;

   if(h_cci==INVALID_HANDLE)
     {
      h_cci=iCCI(Symbol(),Period(),14,PRICE_TYPICAL);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_cci,0,0,3,cci_buffer)<3)
         return(0);

      if(!ArraySetAsSeries(cci_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(cci_buffer[2]<-100 && cci_buffer[1]>-100)
      sig=1;
   else if(cci_buffer[2]>100 && cci_buffer[1]<100)
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.8. Williams %’sinin Aşırı Alış/Aşırı Satış Bölgelerinden Çıkış

Şekil 8. Williams % göstergesi ile aşırı alış ve aşırı satış seviyelerinin aşılması

TradeSignal_08() fonksiyonunu kullanarak, Williams % göstergesinin aşırı alış/aşırı satış bölgelerinden çıkmasıyla ilgili sinyali alacağız; bu bölgeler için seviyeler -20 ve -80 değerlerine sahip seviyelerdir.

Williams %'si -80 seviyesinin altına düşüp daha sonra bu seviyenin üzerine çıktığında satın alırız. Williams % -20 seviyesinin üzerine çıkıp daha sonra bunun altına düştüğünde satarız.

int TradeSignal_08()
  {
   int sig=0;

   if(h_wpr==INVALID_HANDLE)
     {
      h_wpr=iWPR(Symbol(),Period(),14);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_wpr,0,0,3,wpr_buffer)<3)
         return(0);

      if(!ArraySetAsSeries(wpr_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(wpr_buffer[2]<-80 && wpr_buffer[1]>-80)
      sig=1;
   else if(wpr_buffer[2]>-20 && wpr_buffer[1]<-20)
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }
3.9. Bollinger Kanalının Sınırlarından Sıçrama

Şekil 9. Bollinger kanalının sınırından fiyatın sıçraması

TradeSignal_09() fonksiyonunu kullanarak, fiyat Bollinger kanalının sınırlarından sıçradığında sinyali alacağız.

Fiyat Bollinger'in üst sınırını deler veya o sınıra dokunur ve ardından geri dönerse bu, satış sinyalidir. Fiyat Bollinger'in alt sınırını deler veya o sınıra dokunursa bu, satın alma sinyalidir.

int TradeSignal_09()
  {
   int sig=0;

   if(h_bb==INVALID_HANDLE)
     {
      h_bb=iBands(Symbol(),Period(),20,0,2,PRICE_CLOSE);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_bb,1,0,2,bb1_buffer)<2)
         return(0);
      if(CopyBuffer(h_bb,2,0,2,bb2_buffer)<2)
         return(0);
      if(CopyClose(Symbol(),Period(),0,3,Close)<3)
         return(0);
      if(!ArraySetAsSeries(bb1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(bb2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(Close[2]<=bb2_buffer[1] && Close[1]>bb2_buffer[1])
      sig=1;
   else if(Close[2]>=bb1_buffer[1] && Close[1]<bb1_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.10. Standart Sapma Kanalının Sınırlarından Sıçrama

Şekil 10. Fiyatın standart sapma kanalının sınırlarından sıçraması

TradeSignal_10() fonksiyonunu kullanarak, fiyat standart sapma kanalının sınırlarından sıçradığında sinyali alacağız.

Fiyat, standart sapma kanalının üst sınırını deler veya bu sınıra dokunur ve ardından geri dönerse bu, satış sinyalidir. Fiyat, standart sapma kanalının alt sınırını deler veya bu sınıra dokunursa bu, satın alma sinyalidir.

int TradeSignal_10()
  {
   int sig=0;

   if(h_sdc==INVALID_HANDLE)
     {
      h_sdc=iCustom(Symbol(),Period(),"StandardDeviationChannel",14,0,MODE_SMA,PRICE_CLOSE,2.0);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_sdc,0,0,2,sdc1_buffer)<2)
         return(0);
      if(CopyBuffer(h_sdc,1,0,2,sdc2_buffer)<2)
         return(0);
      if(CopyClose(Symbol(),Period(),0,3,Close)<3)
         return(0);
      if(!ArraySetAsSeries(sdc1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(sdc2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(Close[2]<=sdc2_buffer[1] && Close[1]>sdc2_buffer[1])
      sig=1;
   else if(Close[2]>=sdc1_buffer[1] && Close[1]<sdc1_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.11. Fiyat Kanalının Sınırlarından Sıçrayış

Şekil 11. Fiyat Kanalının sınırlarından fiyat sıçraması

TradeSignal_11() fonksiyonunu kullanarak fiyat, Fiyat Kanalının sınırlarından sıçradığında sinyali alırız.

Fiyat, Fiyat Kanalının üst sınırını deler veya dokunur ve ardından geri dönerse, bu satış sinyalidir. Fiyat, Fiyat Kanalının alt sınırını deler veya dokunursa bu, satın alma sinyalidir.

int TradeSignal_11()
  {
   int sig=0;

   if(h_pc==INVALID_HANDLE)
     {
      h_pc=iCustom(Symbol(),Period(),"Price Channel",22);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_pc,0,0,4,pc1_buffer)<4)
         return(0);
      if(CopyBuffer(h_pc,1,0,4,pc2_buffer)<4)
         return(0);
      if(CopyClose(Symbol(),Period(),0,3,Close)<3)
         return(0);
      if(!ArraySetAsSeries(pc1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(pc2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(Close[1]>pc2_buffer[2] && Close[2]<=pc2_buffer[3])
      sig=1;
   else if(Close[1]<pc1_buffer[2] && Close[2]>=pc1_buffer[3])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.12. Zarflar Kanalının Sınırlarından Sıçrayış

Şekil 12. Zarflar kanalının sınırlarından fiyat sıçraması

TradeSignal_12() fonksiyonunu kullanarak, fiyat Zarflar kanalının sınırlarından sıçrarsa sinyali alırız.

Fiyat, Zarflar kanalının üst sınırını deler veya bu sınıra dokunur ve ardından geri dönerse bu, satış sinyalidir. Fiyat, Zarflar kanalının alt sınırını deler veya bu sınıra dokunursa bu, satın alma sinyalidir.

int TradeSignal_12()
  {
   int sig=0;

   if(h_env==INVALID_HANDLE)
     {
      h_env=iEnvelopes(Symbol(),Period(),28,0,MODE_SMA,PRICE_CLOSE,0.1);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_env,0,0,2,env1_buffer)<2)
         return(0);
      if(CopyBuffer(h_env,1,0,2,env2_buffer)<2)
         return(0);
      if(CopyClose(Symbol(),Period(),0,3,Close)<3)
         return(0);
      if(!ArraySetAsSeries(env1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(env2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(Close[2]<=env2_buffer[1] && Close[1]>env2_buffer[1])
      sig=1;
   else if(Close[2]>=env1_buffer[1] && Close[1]<env1_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.13. Donchian Kanalının Kırılımı

Şekil 13. Donchian Kanalı sınırlarının kırılımı

TradeSignal_13() fonksiyonunda, fiyat Donchian kanalının sınırlarını aştığında sinyali alacağız.

Fiyat Donchian kanalının üst sınırını delerse ve kapanış fiyatı bu sınırın üzerinde sabitlenirse bu, satın alma sinyalidir. Fiyat Donchian kanalının alt sınırını delerse ve kapanış fiyatı bu sınırın altında sabitlenirse bu, satış sinyalidir.

int TradeSignal_13()
  {
   int sig=0;

   if(h_dc==INVALID_HANDLE)
     {
      h_dc=iCustom(Symbol(),Period(),"Donchian Channels",24,3,-2);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_dc,0,0,3,dc1_buffer)<3)
         return(0);
      if(CopyBuffer(h_dc,1,0,3,dc2_buffer)<3)
         return(0);
      if(CopyClose(Symbol(),Period(),0,2,Close)<2)
         return(0);
      if(!ArraySetAsSeries(dc1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(dc2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(Close[1]>dc1_buffer[2])
      sig=1;
   else if(Close[1]<dc2_buffer[2])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.14. Gümüş Kanalın Kırılımı

Şekil 14. Gümüş Kanalın sınırlarının atılımı

TradeSignal_14() fonksiyonunda, fiyat Gümüş Kanalın sınırlarını aştığında sinyali alacağız.  Gümüş Kanal göstergesi, destek ve direnç seviyeleri olarak da işlev görebilecek 8 sınır çizer. Sinyali elde etmek için 2 orta sınır kullanacağız. 

Fiyat Gümüş Kanalın üst sınırını delerse ve kapanış fiyatı bu sınırın üzerinde sabitlenirse bu, satın alma sinyalidir. Fiyat Gümüş Kanalın alt sınırını delerse ve kapanış fiyatı bu sınırın altında sabitlenirse bu, satış sinyalidir.

int TradeSignal_14()
  {
   int sig=0;

   if(h_sc==INVALID_HANDLE)
     {
      h_sc=iCustom(Symbol(),Period(),"Silver-channels",26,38.2,23.6,0,61.8);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_sc,0,0,2,sc1_buffer)<2)
         return(0);
      if(CopyBuffer(h_sc,1,0,2,sc2_buffer)<2)
         return(0);
      if(CopyClose(Symbol(),Period(),0,3,Close)<3)
         return(0);
      if(!ArraySetAsSeries(sc1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(sc2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(Close[2]<sc1_buffer[1] && Close[1]>sc1_buffer[1])
      sig=1;
   else if(Close[2]>sc2_buffer[1] && Close[1]<sc2_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.15. Gallagher Kanalında Kırılım

Şekil 15. Gallagher kanalının sınırlarının kırılımı

TradeSignal_15() kanalında fiyat Gallagher kanalının sınırlarını aştığında sinyali alacağız. Gallagher kanalının göstergesi, 10 gün boyunca maksimumlar ve minimumlar tarafından çizilir. 

Fiyat Gallagher kanalının üst sınırını delerse ve kapanış fiyatı bu sınırın üzerinde sabitlenirse bu, satın alma sinyalidir. Fiyat Gallagher kanalının alt sınırını delerse ve kapanış fiyatı bu sınırın altında sabitlenirse bu, satış sinyalidir.

int TradeSignal_15()
  {
   int sig=0;

   if(h_gc==INVALID_HANDLE)
     {
      h_gc=iCustom(Symbol(),Period(),"PriceChannelGalaher");
      return(0);
     }
   else
     {
      if(CopyBuffer(h_gc,0,0,3,gc1_buffer)<3)
         return(0);
      if(CopyBuffer(h_gc,1,0,3,gc2_buffer)<3)
         return(0);
      if(CopyClose(Symbol(),Period(),0,2,Close)<2)
         return(0);
      if(!ArraySetAsSeries(gc1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(gc2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(Close,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(Close[1]>gc1_buffer[2])
      sig=1;
   else if(Close[1]<gc2_buffer[2])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.16. NRTR'ye Göre Trend Değişimi

Şekil 16. NRTR göstergesini kullanarak bir trend değişikliğinin tanımlanması

TradeSignal_16() fonksiyonunda, NRTR trendi değiştiğinde sinyali alacağız.

NRTR göstergesi yükselen bir trend gösteriyorsa bu, satın alma sinyalidir. NRTR azalan bir trend gösteriyorsa bu, satış sinyalidir.

int TradeSignal_16()
  {
   int sig=0;

   if(h_nrtr==INVALID_HANDLE)
     {
      h_nrtr=iCustom(Symbol(),Period(),"NRTR",40,2.0);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_nrtr,0,0,2,nrtr1_buffer)<2)
         return(0);
      if(CopyBuffer(h_nrtr,1,0,2,nrtr2_buffer)<2)
         return(0);
      if(!ArraySetAsSeries(nrtr1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(nrtr2_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(nrtr1_buffer[1]>0)
      sig=1;
   else if(nrtr2_buffer[1]>0)
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.17. Timsaha Göre Trend Değişimi

Şekil 17. Timsaha göre trend değişimi

TradeSignal_17() fonksiyonunda, Timsah trendi değiştiğinde sinyali alacağız.

Çene, Dişler ve Dudaklar kapalı ve bükülmüşse Timsah uyuyacaktır veya zaten uyuyordur. Uyuduğu zaman açlığı artar ve ne kadar çok uyursa, uyandığında o kadar aç olur. Uyandığında yaptığı ilk şey ağzını açıp esnemektir. Sonra yemeği koklamaya başlar - boğa ya da ayı eti ve sonra onu avlamaya başlar. Timsah yeterince yediğinde yiyecek fiyatına olan ilgisini kaybeder (Denge Çizgileri birleşir); kârı sabitlemenin zamanı gelmiştir.

int TradeSignal_17()
  {
   int sig=0;

   if(h_al==INVALID_HANDLE)
     {
      h_al=iAlligator(Symbol(),Period(),13,0,8,0,5,0,MODE_SMMA,PRICE_MEDIAN);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_al,0,0,2,al1_buffer)<2)
         return(0);
      if(CopyBuffer(h_al,1,0,2,al2_buffer)<2)
         return(0);
      if(CopyBuffer(h_al,2,0,2,al3_buffer)<2)
         return(0);
      if(!ArraySetAsSeries(al1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(al2_buffer,true))
         return(0);
      if(!ArraySetAsSeries(al3_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(al3_buffer[1]>al2_buffer[1] && al2_buffer[1]>al1_buffer[1])
      sig=1;
   else if(al3_buffer[1]<al2_buffer[1] && al2_buffer[1]<al1_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.18. AMA’ya Göre Trend Değişimi

Şekil 18. AMA’ya göre trend değişimi

TradeSignal_18() fonksiyonunda, AMA trendi değiştiğinde sinyali alacağız.

AMA göstergesi yukarı doğru yönlendirilirse bu, satın alma sinyalidir. AMA aşağıya doğru yönlendirilirse bu, satış sinyalidir.

int TradeSignal_18()
  {
   int sig=0;

   if(h_ama==INVALID_HANDLE)
     {
      h_ama=iAMA(Symbol(),Period(),9,2,30,0,PRICE_CLOSE);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_ama,0,0,3,ama_buffer)<3)
         return(0);
      if(!ArraySetAsSeries(ama_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(ama_buffer[2]<ama_buffer[1])
      sig=1;
   else if(ama_buffer[2]>ama_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.19. Harika Osilatörün Renk Değişimi

Şekil 19. Harika Osilatör göstergesini kullanarak bir trend değişikliğinin tanımlanması

TradeSignal_19() fonksiyonunda, Harika Osilatör histogramının rengi değiştiğinde sinyali alacağız.

MQL5'in özelliklerinden biri, #property indicator_colorN özelliklerinde ayarlanan çizgilerin renk indislerinin saklanabileceği göstergeler için tampon oluşturma imkanıdır. Harika Osilatör histogramının rengi yeşil olduğunda bu, satın alma sinyalidir. Rengi kırmızıya dönerse bu, satış sinyalidir.

int TradeSignal_19()
  {
   int sig=0;

   if(h_ao==INVALID_HANDLE)
     {
      h_ao=iAO(Symbol(),Period());
      return(0);
     }
   else
     {
      if(CopyBuffer(h_ao,1,0,20,ao_buffer)<20)
         return(0);
      if(!ArraySetAsSeries(ao_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(ao_buffer[1]==0)
      sig=1;
   else if(ao_buffer[1]==1)
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }

3.20. Ichimoku’ya Göre Trend Değişimi

Şekil 20. Ichimoku göstergesini kullanarak bir trend değişikliğinin tanımlanması

TradeSignal_20() fonksiyonunda, Ichimoku trendi değiştiğinde sinyali alacağız. Bu amaçla Tenkan-sen ve Kijun-sen çizgilerinin kesişimini analiz edeceğiz.

Satın alma sinyali, Tenkan-sen çizgisi Kijun-sen'i aşağıdan yukarıya doğru geçtiğinde oluşturulur. Yukarıdan aşağıya geçiş, satış sinyalidir.

int TradeSignal_20()
  {
   int sig=0;

   if(h_ich==INVALID_HANDLE)
     {
      h_ich=iIchimoku(Symbol(),Period(),9,26,52);
      return(0);
     }
   else
     {
      if(CopyBuffer(h_ich,0,0,2,ich1_buffer)<2)
         return(0);
      if(CopyBuffer(h_ich,1,0,2,ich2_buffer)<2)
         return(0);
      if(!ArraySetAsSeries(ich1_buffer,true))
         return(0);
      if(!ArraySetAsSeries(ich2_buffer,true))
         return(0);
     }
//--- check the condition and set a value for sig
   if(ich1_buffer[1]>ich2_buffer[1])
      sig=1;
   else if(ich1_buffer[1]<ich2_buffer[1])
      sig=-1;
   else sig=0;

//--- return the trade signal
   return(sig);
  }


4. Bunu Bir Gösterge Olarak Yapmak

Artık hazır gösterge bloklarına sahip olduğumuza göre, seçilen tüm yöntemler bazında sinyalleri gösteren bir gösterge yazmaya başlayabiliriz. Oluşturulan şablonu kullanarak herhangi bir göstergeden sinyal alımını gerçekleştirebiliriz; bir sinyal koşulunu doğru bir şekilde formüle etmek ve koda eklemek yeterlidir.

Esnek olmayan yerleşik parametrelere sahip bir gösterge yazalım. Göstergelerin sinyalleri, grafiğin sağ tarafında oklar (yukarı ok - ancak, aşağı - satış, çapraz - sinyal yok) şeklinde çizilecektir. Okları çizmek için standart Wingdings yazı tipini alalım. Ayrıca bir sembolün grafiğinde sinyaller hakkındaki bilgileri görüntülemek için başka fonksiyonlar oluşturmamız gerekiyor. Bunları ayrı bir blokta, yeni fonksiyonlar ekleyerek kendi programlarınızı yazmak için kullanılabilecek bir kitaplık olarak birleştireceğiz. Bu kitaplığa LibFunctions adını verelim.

Gelecekteki göstergemizin başlığında, dosyanın sinyal üretme fonksiyonlarıyla bağlantısını ve sinyalin grafiksel gösterimi için gerekli olan içe aktarma fonksiyonunu, ayrıca göstergeden alınan sinyalin türünü depolayacak olan globalscape üzerindeki değişkenleri yazın.

//--- Connect necessary libraries of functions
#include <SignalTrade.mqh>
//--- Import of functions from the LibFunctions library
#import "LibFunctions.ex5"
void SetLabel(string nm,string tx,ENUM_BASE_CORNER cn,ENUM_ANCHOR_POINT cr,int xd,int yd,string fn,int fs,double yg,color ct);
string arrow(int sig);
color Colorarrow(int sig);
#import
//+------------------------------------------------------------------+
//| Declare variables for storing signals of indicators              |
//+------------------------------------------------------------------+
int SignalMA;
int SignalMACD;
int SignalPC;
int SignalACADX;
int SignalST;
int SignalRSI;
int SignalCCI;
int SignalWPR;
int SignalBB;
int SignalSDC;
int SignalPC2;
int SignalENV;
int SignalDC;
int SignalSC;
int SignalGC;
int SignalNRTR;
int SignalAL;
int SignalAMA;
int SignalAO;
int SignalICH;

Daha önce de belirttiğim gibi, göstergeler terminale sadece bir kez yüklenir ve o göstergelere yönelik işaretçiler (tanıtıcı değerler) oluşturulur; bu nedenle, bu fonksiyon program başlangıcında yalnızca bir kez çalıştırıldığından, bunların oluşturmalarını OnInit() fonksiyonuna uygulayalım.

int OnInit()
  {
//--- create indicator handles
   h_ma1=iMA(Symbol(),Period(),8,0,MODE_SMA,PRICE_CLOSE);
   h_ma2=iMA(Symbol(),Period(),16,0,MODE_SMA,PRICE_CLOSE);
   h_macd=iMACD(Symbol(),Period(),12,26,9,PRICE_CLOSE);
   h_pc=iCustom(Symbol(),Period(),"Price Channel",22);
   h_acadx=iCustom(Symbol(),Period(),"AdaptiveChannelADX",14);
   h_stoh=iStochastic(Symbol(),Period(),5,3,3,MODE_SMA,STO_LOWHIGH);
   h_rsi=iRSI(Symbol(),Period(),14,PRICE_CLOSE);
   h_cci=iCCI(Symbol(),Period(),14,PRICE_TYPICAL);
   h_wpr=iWPR(Symbol(),Period(),14);
   h_bb=iBands(Symbol(),Period(),20,0,2,PRICE_CLOSE);
   h_sdc=iCustom(Symbol(),Period(),"StandardDeviationChannel",14,0,MODE_SMA,PRICE_CLOSE,2.0);
   h_env=iEnvelopes(Symbol(),Period(),28,0,MODE_SMA,PRICE_CLOSE,0.1);
   h_dc=iCustom(Symbol(),Period(),"Donchian Channels",24,3,-2);
   h_sc=iCustom(Symbol(),Period(),"Silver-channels",26,38.2,23.6,0,61.8);
   h_gc=iCustom(Symbol(),Period(),"PriceChannelGalaher");
   h_nrtr=iCustom(Symbol(),Period(),"NRTR",40,2.0);
   h_al=iAlligator(Symbol(),Period(),13,0,8,0,5,0,MODE_SMMA,PRICE_MEDIAN);
   h_ama=iAMA(Symbol(),Period(),9,2,30,0,PRICE_CLOSE);
   h_ao=iAO(Symbol(),Period());
   h_ich=iIchimoku(Symbol(),Period(),9,26,52);
   return(0);
  }

Tüm ana hesaplamalar OnCalculate() fonksiyonunda gerçekleştirilir; oraya gösterge kodunun geri kalanını yerleştireceğiz.

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[])
  {
//---assign the signal value to the variable
   SignalMA    = TradeSignal_01();
   SignalMACD  = TradeSignal_02();
   SignalPC    = TradeSignal_03();
   SignalACADX = TradeSignal_04();
   SignalST    = TradeSignal_05();
   SignalRSI   = TradeSignal_06();
   SignalCCI   = TradeSignal_07();
   SignalWPR   = TradeSignal_08();
   SignalBB    = TradeSignal_09();
   SignalSDC   = TradeSignal_10();
   SignalPC2   = TradeSignal_11();
   SignalENV   = TradeSignal_12();
   SignalDC    = TradeSignal_13();
   SignalSC    = TradeSignal_14();
   SignalGC    = TradeSignal_15();
   SignalNRTR  = TradeSignal_16();
   SignalAL    = TradeSignal_17();
   SignalAMA   = TradeSignal_18();
   SignalAO    = TradeSignal_19();
   SignalICH   = TradeSignal_20();

//--- draw graphical objects on the chart in the upper left corner
   int size=((int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS)/22);
   int i=0;
   int x=10;
   int y=0;
   int fz=size-4;

   y+=size;
   SetLabel("arrow"+(string)i,arrow(SignalMA),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalMA));
   x+=size;
   SetLabel("label"+(string)i,"Moving Average",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalMACD),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalMACD));
   x+=size;
   SetLabel("label"+(string)i,"MACD",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalPC),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalPC));
   x+=size;
   SetLabel("label"+(string)i,"Price Channell",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalACADX),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalACADX));
   x+=size;
   SetLabel("label"+(string)i,"Adaptive Channel ADX",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalST),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalST));
   x+=size;
   SetLabel("label"+(string)i,"Stochastic Oscillator",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalRSI),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalRSI));
   x+=size;
   SetLabel("label"+(string)i,"RSI",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalCCI),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalCCI));
   x+=size;
   SetLabel("label"+(string)i,"CCI",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalWPR),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalWPR));
   x+=size;
   SetLabel("label"+(string)i,"WPR",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalBB),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalBB));
   x+=size;
   SetLabel("label"+(string)i,"Bollinger Bands",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalSDC),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalSDC));
   x+=size;
   SetLabel("label"+(string)i,"StDevChannel",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalPC2),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalPC2));
   x+=size;
   SetLabel("label"+(string)i,"Price Channell 2",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalENV),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalENV));
   x+=size;
   SetLabel("label"+(string)i,"Envelopes",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalDC),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalDC));
   x+=size;
   SetLabel("label"+(string)i,"Donchian Channels",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalSC),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalSC));
   x+=size;
   SetLabel("label"+(string)i,"Silver-channels",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalGC),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalGC));
   x+=size;
   SetLabel("label"+(string)i,"Galaher Channel",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalNRTR),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalNRTR));
   x+=size;
   SetLabel("label"+(string)i,"NRTR",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalAL),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalAL));
   x+=size;
   SetLabel("label"+(string)i,"Alligator",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalAMA),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalAMA));
   x+=size;
   SetLabel("label"+(string)i,"AMA",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalAO),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalAO));
   x+=size;
   SetLabel("label"+(string)i,"Awesome oscillator",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);
   i++;y+=size;x=10;
   SetLabel("arrow"+(string)i,arrow(SignalICH),CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y+4,"Wingdings",fz-2,0,Colorarrow(SignalICH));
   x+=size;
   SetLabel("label"+(string)i,"Ichimoku Kinko Hyo",CORNER_RIGHT_UPPER,ANCHOR_RIGHT_UPPER,x,y,"Arial",fz,0,BlueViolet);

   return(rates_total);
  }

Pekala, göstergemiz hazır. Sonunda grafikte aşağıdaki resme sahibiz.



5. Uzman Danışman Olarak Yapmak

Benzer şekilde, göstergenin sinyalini grafik üzerinde gösteren bir Uzman Danışman yazabiliriz. Grafiksel kontrol unsurları ile bir bilgi sistemi uygulayalım. Gerekli göstergeyi seçmek ve parametrelerini grafik arayüz üzerinden ayarlamak mümkündür.


Grafik arayüzün uygulamasını tartışmayacağız; bununla ilgili bilgileri Alım Satım için MQL5'te Aktif Kontrol Panelleri Oluşturma makalesinde bulabilirsiniz.

Göstergelerin ayarlarını grafik arayüzümüz üzerinden değiştirmek için SignalTrade.mqh kitaplığımızı geliştirelim ve adını SignalTradeExp.mqh koyalım.

Her şeyden önce, göstergelerin ayarlarını depolamak için ek değişkenlere ihtiyacımız var.

//--- input parameters Moving Average
int                periodma1=8;
int                periodma2=16;
ENUM_MA_METHOD     MAmethod=MODE_SMA;
ENUM_APPLIED_PRICE MAprice=PRICE_CLOSE;
//--- input parameters MACD
int                FastMACD=12;
int                SlowMACD=26;
int                MACDSMA=9;
ENUM_APPLIED_PRICE MACDprice=PRICE_CLOSE;
//--- input parameters Price Channel
int                PCPeriod=22;
//--- input parameters Adaptive Channel ADX
int                ADXPeriod=14;
//--- input parameters Stochastic Oscillator
int                SOPeriodK=5;
int                SOPeriodD=3;
int                SOslowing=3;
ENUM_MA_METHOD     SOmethod=MODE_SMA;
ENUM_STO_PRICE     SOpricefield=STO_LOWHIGH;
//--- input parameters RSI
int                RSIPeriod=14;
ENUM_APPLIED_PRICE RSIprice=PRICE_CLOSE;
//--- input parameters CCI
int                CCIPeriod=14;
ENUM_APPLIED_PRICE CCIprice=PRICE_TYPICAL;
//--- input parameters WPR
int                WPRPeriod=14;
//--- input parameters Bollinger Bands
int                BBPeriod=20;
double             BBdeviation=2.0;
ENUM_APPLIED_PRICE BBprice=PRICE_CLOSE;
//--- input parameters Standard Deviation Channel
int                SDCPeriod=14;
double             SDCdeviation=2.0;
ENUM_APPLIED_PRICE SDCprice=PRICE_CLOSE;
ENUM_MA_METHOD     SDCmethod=MODE_SMA;
//--- input parameters Price Channel 2
int                PC2Period=22;
//--- input parameters Envelopes
int                ENVPeriod=14;
double             ENVdeviation=0.1;
ENUM_APPLIED_PRICE ENVprice=PRICE_CLOSE;
ENUM_MA_METHOD     ENVmethod=MODE_SMA;
//--- input parameters Donchian Channels
int                DCPeriod=24;
int                DCExtremes=3;
int                DCMargins=-2;
//--- input parameters Silver-channels
int                SCPeriod=26;
double             SCSilvCh=38.2;
double             SCSkyCh=23.6;
double             SCFutCh=61.8;
//--- input parameters NRTR
int                NRTRPeriod   =  40;
double             NRTRK        =  2.0;
//--- input parameters Alligator
int                ALjawperiod=13;
int                ALteethperiod=8;
int                ALlipsperiod=5;
ENUM_MA_METHOD     ALmethod=MODE_SMMA;
ENUM_APPLIED_PRICE ALprice=PRICE_MEDIAN;
//--- input parameters AMA
int                AMAperiod=9;
int                AMAfastperiod=2;
int                AMAslowperiod=30;
ENUM_APPLIED_PRICE AMAprice=PRICE_CLOSE;
//--- input parameters Ichimoku Kinko Hyo
int                IKHtenkansen=9;
int                IKHkijunsen=26;
int                IKHsenkouspanb=52;

Göstergelerin sabit değerlerini değişkenlerle değiştirin. Diğer şeyler değişmeden bırakılmalıdır.

h_ma1=iMA(Symbol(),Period(),periodma1,0,MAmethod,MAprice);

Önemli bir nokta da bilgisayar belleğinin ekonomik kullanılmasıdır; ayarları değiştirirken göstergenin eski ayarlara sahip kopyasının çıkarılması ve yenisinin yüklenmesi gerekir. Aşağıdaki fonksiyon kullanılarak yapılabilir:

bool  IndicatorRelease(
   int       indicator_handle,     // indicator handle
   );
   if(id==CHARTEVENT_OBJECT_ENDEDIT && sparam=="PIPSetEditMA2")
     {
      periodma2=(int)ObjectGetString(0,"PIPSetEditMA2",OBJPROP_TEXT);
      ObjectSetString(0,"PIPSetEditMA2",OBJPROP_TEXT,(string)periodma2);
      //--- unload old copy of the indicator
      IndicatorRelease(h_ma2);
      //--- create new copy of the indicator
      h_ma2=iMA(Symbol(),Period(),periodma2,0,MAmethod,MAprice);
      ChartRedraw();
     }

Sonuç

Böylece göstergelerden gelen bilgileri nasıl okuyacağımızı ve Uzman Danışmana nasıl aktaracağımızı öğrendik. Bu şekilde herhangi bir göstergeden sinyaller alabilirsiniz.

Not

  • SignalTrade.mq5, AdaptiveChannelADX.mq5, Donchian Channels.mq5, NRTR.mq5, Price Channel.mq5, PriceChannelGalaher.mq5, Silver-channels.mq5, StandardDeviationChannel.mq5 göstergelerinin dosyası, ...\MQL5\Indicators klasörüne kopyalanmalıdır.
  • SignalTrade.mqh ve SignalTradeExp.mqh içerik dosyaları ...\MQL5\Include klasörüne kopyalanmalıdır.
  • LibFunctions.mq5 fonksiyon kitaplığı ...\MQL5\Libraries klasörüne kopyalanmalıdır.
  • ExpSignalTrade.mq5 Uzman Danışman ...\MQL5\Experts dizinine kopyalanmalıdır.

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

Ekli dosyalar |
indicators.zip (8.9 KB)
expsignaltrade.mq5 (165.84 KB)
signaltrade.mq5 (10.57 KB)
signaltrade.mqh (20.16 KB)
signaltradeexp.mqh (23.26 KB)
Alım Satım Robotunun Prototipi Alım Satım Robotunun Prototipi
Bu makale, alım satım sistemlerinin algoritmaları ve elemanlarını oluşturma ilkelerini özetlemekte ve sistematikleştirmektedir. Makale, uzman algoritmasının tasarlanmasını ele almaktadır. Örnek olarak, alım satım sistemlerinin hızlı ve kolay bir şekilde geliştirilmesi için kullanılabilen CExpertAdvisor sınıfı düşünülmüştür.
Başka Bir Göstergeye Dayalı Bir Gösterge Nasıl Yazılır? Başka Bir Göstergeye Dayalı Bir Gösterge Nasıl Yazılır?
MQL5'te, hem sıfırdan hem de zaten mevcut olan, istemci terminalinde yerleşik veya özel bir gösterge temelinde bir gösterge yazabilirsiniz. Burada ayrıca iki yolunuz var - bir göstergeyi ona yeni hesaplamalar ve grafik stilleri ekleyerek geliştirmek veya istemci terminalinde yerleşik bir gösterge veya iCustom() ya da IndicatorCreate() fonksiyonları aracılığıyla özel bir gösterge kullanmak.
Kendi Takip Eden Durdurma (Trailing Stop) Emrinizi Nasıl Oluşturabilirsiniz? Kendi Takip Eden Durdurma (Trailing Stop) Emrinizi Nasıl Oluşturabilirsiniz?
Yatırımcının temel kuralı - kârın büyümesine izin verin, zararları kesin! Bu makale, bu kuralın izlenmesine izin veren temel tekniklerden birini, pozisyon kârını artırdıktan sonra koruyucu durdurma seviyesini (Zararı Durdur seviyesi), yani Takip Eden Durdurma (Trailing Stop) seviyesini hareket ettirmeyi ele almaktadır. SAR ve NRTR göstergelerinde takip eden durdurma için bir sınıf oluşturmaya yönelik adım adım prosedürü bulacaksınız. Herkes bu takip eden durdurmayı kendi uzmanlarına ekleyebilecek veya hesaplarındaki pozisyonları kontrol etmek için bağımsız olarak kullanabilecek.
Uzman Danışmanda Para Yönetimi için fonksiyonlar Uzman Danışmanda Para Yönetimi için fonksiyonlar
Alım satım stratejilerinin geliştirilmesi, öncelikli olarak, piyasaya giriş ve çıkış için kalıpların aranmasının yanı sıra pozisyonların muhafaza edilmesine odaklanmaktadır. Eğer bazı modelleri otomatik alım salım için kurallar halinde resmileştirebiliyorsak, bu durumda yatırımcı, pozisyonların hacmini, marjların büyüklüğünü hesaplamanın yanı sıra otomatikleştirilmiş bir açık pozisyonu güvence altına almak için güvenli bir ipotek fonu seviyesini muhafaza etme sorunuyla karşı karşıyadır. Bu yazıda MQL5 dilini, bu hesaplamaları yürütmek için basit örnekler oluşturmak için kullanacağız.