![MQL5'te 20 Alım Satım Sinyali](https://c.mql5.com/i/articles/overlay.png)
MQL5'te 20 Alım Satım Sinyali
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
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
![Alım Satım Robotunun Prototipi](https://c.mql5.com/2/0/Prototype_Expert_Advisor_MQL5.png)
![Başka Bir Göstergeye Dayalı Bir Gösterge Nasıl Yazılır?](https://c.mql5.com/2/0/indicator_based_on_other_MQL5__1.png)
![Kendi Takip Eden Durdurma (Trailing Stop) Emrinizi Nasıl Oluşturabilirsiniz?](https://c.mql5.com/2/0/Trailing_Stop_MQL5.png)
![Uzman Danışmanda Para Yönetimi için fonksiyonlar](https://c.mql5.com/2/0/money_management_MQL5__1.png)
![MQL5 - MetaTrader 5 müşteri terminalinde yerleşik ticaret stratejileri dili](https://c.mql5.com/i/registerlandings/logo-2.png)
- Ücretsiz ticaret uygulamaları
- İşlem kopyalama için 8.000'den fazla sinyal
- Finansal piyasaları keşfetmek için ekonomik haberler
Gizlilik ve Veri Koruma Politikasını ve MQL5.com Kullanım Şartlarını kabul edersiniz