
MQL5 Sihirbazı: Hesaplanan Fiyatlardan Talimatlar, Zarar Durdur ve Kar Al uygulama. Standart Kitaplık Uzantısı
Giriş
MQL5 Standart Kitaplık, katı bir mimari gerektiren büyük projelerin geliştirilmesinde faydalı bir yardımcıdır. MQL5 Sihirbazı, diyalog modunda birkaç dakika içinde, fazla tahmin edilemeyecek kadar kapsamlı bir şema halinde hazır parçaların birleştirilmesine izin verir. MQL5 Sihirbazı, Expert'in tüm parçalarını bir araya getirmeyi otomatikleştirir ve modül parametrelerini, tanıtıcılara göre Expert'te otomatik olarak bildirir. Dahil edilen çok sayıda çeşitli modül olduğunda, bu tür otomasyon çok fazla zaman ve rutin işlemler tasarrufu sağlar.
Kulağa hoş geliyor, ancak bariz bir dezavantaj var; Sihirbaz ile standart sınıflara dayalı olarak oluşturulan alım satım sistemlerinin yetenekleri sınırlıdır. Bu makale, oluşturulan Uzmanların işlevselliğini önemli ölçüde genişletmeye izin veren evrensel bir yöntemi ele almaktadır. Bu yöntem uygulandığında, Sihirbaz ve standart modüllerle uyumluluk aynı kalır.
Yöntemin fikri, Nesneye Yönelik Programlama'da kalıtım ve polimorfizm mekanizmalarını kullanmak veya oluşturulan Expert'lerin kodunda standart sınıfların yerine geçecek sınıflar oluşturmaktır. Bu şekilde, Sihirbazın ve Standart Kitaplığın tüm avantajlarından yararlanılır, bu da gerekli yeteneklere sahip bir Expert'in geliştirilmesiyle sonuçlanır. Yine de buraya ulaşmak için kodun sadece dört dizeyle biraz azaltılması gerekir.
Bu makalenin pratik amacı, oluşturulan Expert'lere, yalnızca mevcut fiyattan belirtilen mesafede değil, gerekli fiyat seviyelerinde talimat verme, Zararı Durdurma ve Kar Alma yeteneği eklemektir.
Benzer fikir "MQL5 Sihirbazı: Bir EA'ya Herhangi Bir Fiyatta Bekleyen Talimatları Açmayı Öğretme" makalesinde tartışıldı. Önerilen çözümün önemli dezavantajı, alım satım sinyali modülünün parametresinin alt filtreden "zorla" değiştirilmesidir. Bu yaklaşım, çok sayıda modülle çalışmayı ve süreç optimizasyonu için Sihirbazı kullanmayı desteklemez.
Standart sınıflardan devralınan sınıflarda herhangi bir fiyattan talimat verme, Zarar Durdur ve Kar Al işlemlerinin uygulanması daha ayrıntılı olarak ele alınmaktadır. Bununla birlikte, modüller arasında herhangi bir çakışma imkansızdır. Umarım bu makale bir örnek teşkil eder ve okuyuculara standart çerçeve üzerinde kendi geliştirmelerini yazmaları için ilham verir ve ayrıca kullanıcıların geliştirilen Kitaplık uzantısını uygulamalarına izin verir.
1. Karar Vermenin Standart Algoritması
MQL5 Sihirbazında oluşturulan uzmanlar, CExpert sınıf örneğini temel alır. CExpertSignal sınıfının nesnesinin işaretçisi bu sınıfta bildirildi. Makalede ayrıca bu nesne, kısalık uğruna ana sinyal olarak adlandırılır. Ana sinyal, alt filtrelere yönelik işaretçiler içerir (sinyal modülleri, CExpertSignal sınıfının mirasçılarıdır).
Açık pozisyon ve talimat yoksa Expert, yeni bir onay işareti üzerinde bir pozisyon açma fırsatını kontrol etmek için ana sinyale başvurur. Ana sinyal, alt filtreleri tek tek sorgular ve elde edilen tahmine göre ağırlıklı ortalama tahmini (yön) hesaplar. Bunun değeri, eşiği (ana sinyaldeki m_threshold_open parametresinin değeri) aşarsa talimat parametreleri ve bool tipi koşullar için kontrol sonuçları Expert'e iletilir. Bu koşullar karşılanırsa ya piyasa fiyatında bir pozisyon açılır ya da belli bir mesafede bekleyen bir talimat açılır (bkz. Şekil 1). Zarar Durdurma yalnızca sabit bir mesafeye yerleştirilebilir. Açılış fiyatı başlangıçları, Zarar Durdur ve piyasa fiyatından Kar Al işlemleri Expert ayarlarında belirtilir ve ana sinyalde, m_price_level, m_stop_level ve m_take_level değişkenlerinde sırasıyla saklanır.
Bu nedenle, şu anda bir talimatın verilebilmesi için iki koşulun karşılanması gerekir:
- Mevcut sembol için açık pozisyon yok;
- Ağırlıklı ortalama tahminin mutlak değeri, eşik değerini aşar; bu da bir trendin oldukça güçlü olduğu anlamına gelir.
Şek. 1. Piyasaya girerken karar verme formasyonu
Şekil 1'deki mevcut karar verme modeli, MQL5 Sihirbazının uygulama alanını önemli ölçüde sınırlandırmaktadır. Sabit Zarar Durdur işleminin değerine sahip stratejiler, değişken volatilite nedeniyle uzun vadeli alım satımda nadiren etkilidir. Bekleyen talimatları kullanan sistemler genellikle bunları dinamik olarak hesaplanmış seviyelere yerleştirmeyi gerektirir.
2. Karar Vermenin Değiştirilmiş Algoritması
Seviyeleri hesaplama ve talimat verme perspektifinden, sinyal modülleri bir tahmin değerinden başka bir şey üretemediğinden ve ana sinyal seviyelerle çalışmak için tasarlanmadığından bu bir çıkmaz durumdur. Bu konuda tavsiye edilir:
- Talimat parametreleri üretebilen yeni tür sinyal modülleri (bunlara fiyat modülleri diyeceğiz) tanıtmak;
- Bu parametreleri işlemek için ana sinyali eğitin, yani en iyilerini seçin ve Expert'e iletin.
Değiştirilmiş algoritma (Şek. 2), bekleyen talimatların yanı sıra diğer taleplerle de çalışmaya izin verir. Bu algoritmanın özü, giriş noktasını (fiyatı) bir trend tanımlamadan (ağırlıklı ortalama tahmini) ayırmasıdır. Bu, bir karar vermek için filtrelerle tercih edilen alım satım yönünün tanımlandığı ve fiyat modüllerinden elde edilen uygun yöne sahip bir dizi talimat parametresinin seçildiği anlamına gelir. Kullanılabilir birkaç benzer set varsa set, en büyük ağırlığa (m_weight parametre değeri seçilir) sahip modülden alınır. Yön belirlenmişse ancak şu anda uygun giriş noktası yoksa Expert etkin değildir.
Şek. 2. Piyasaya girerken değiştirilen karar verme formasyonu
Yeni bir talimat vermek için aşağıdaki gereksinimlerin karşılanması gerekir:
- Mevcut sembol için açık pozisyon ve talimat yok;
- Ağırlıklı ortalama tahmininin mutlak değeri eşik değerini aşıyor;
- Talimatın en az bir açılış fiyatı bulundu.
Şekil 2'deki algoritma, birçok olası giriş noktasının ele alınmasına, yönlere göre filtrelenmesine ve bir Expert'te en iyisinin seçilmesine olanak tanır.
3. Expert ve Sinyal Modülünün Değiştirilmiş Sınıflarının Geliştirilmesi
Kitaplığın uzantısı iki sınıfa dayanmaktadır: CExpertSignalAdvanced ve CExpertAdvanced, sırasıyla CExpertSignal ve CExpert uzantısından devralınır.
Expert'in farklı blokları arasında veri alışverişi için kullanılan arayüzleri değiştirmeyi amaçlayan yeni yetenekler özellikler eklemeye yönelik tüm önlemler. Örneğin algoritmayı Şek. 2'deki kalıba göre uygulamak için ana sinyalin (sınıf CExpertSignalAdvanced) fiyat modülleri (bu sınıfın torunları) ile etkileşimini organize etmek gerekir. Veri değiştiğinde önceden verilmiş talimatların güncellenmesi, Expert'in (sınıf CExpertAdvanced) ana sinyalle etkileşimini gerektirir.
Bu aşamada, açık pozisyonlar için Şek. 2'deki modeli uygulayacağız ve parametreler değiştiğinde (örneğin daha uygun bir giriş noktası göründüğünde) halihazırda verilmiş olan talimatların güncellenmesini organize edeceğiz. CExpertSignalAdvanced sınıfını ele alalım.
3.1. CExpertSignalAdvanced
Bu sınıf, üst öğesinin sinyal modülleri için temel olduğu gibi, ana sinyal rolünde üst öğesinin yerini alacak ve fiyat modülleri için temel sınıf olacaktır.
class CExpertSignalAdvanced : public CExpertSignal { protected: //---data members for storing parameters of the orders being placed double m_order_open_long; //opening price of the order to buy double m_order_stop_long; //Stop Loss of the order to buy double m_order_take_long; //Take Profit of the order to buy datetime m_order_expiration_long; //expiry time of the order to buy double m_order_open_short; //opening price of the order to sell double m_order_stop_short; //Stop Loss of the order to sell double m_order_take_short; //Take Profit of the order to sell datetime m_order_expiration_short; //expiry time of the order to sell //--- int m_price_module; //index of the first price module in the m_filters array public: CExpertSignalAdvanced(); ~CExpertSignalAdvanced(); virtual void CalcPriceModuleIndex() {m_price_module=m_filters.Total();} virtual bool CheckOpenLong(double &price,double &sl,double &tp,datetime &expiration); virtual bool CheckOpenShort(double &price,double &sl,double &tp,datetime &expiration); virtual double Direction(void); //calculating weighted average forecast based on the data received from signal modules virtual double Prices(void); //updating of parameters of the orders being placed according to the data received from price modules virtual bool OpenLongParams(double &price,double &sl,double &tp,datetime &expiration); virtual bool OpenShortParams(double &price,double &sl,double &tp,datetime &expiration); virtual bool CheckUpdateOrderLong(COrderInfo *order_ptr,double &open,double &sl,double &tp,datetime &ex); virtual bool CheckUpdateOrderShort(COrderInfo *order_ptr,double &open,double &sl,double &tp,datetime &ex); double getOpenLong() { return m_order_open_long; } double getOpenShort() { return m_order_open_short; } double getStopLong() { return m_order_stop_long; } double getStopShort() { return m_order_stop_short; } double getTakeLong() { return m_order_take_long; } double getTakeShort() { return m_order_take_short; } datetime getExpLong() { return m_order_expiration_long; } datetime getExpShort() { return m_order_expiration_short; } double getWeight() { return m_weight; } };
Talimat parametrelerini depolamak için veri üyeleri, CExpertSignalAdvanced sınıfında bildirildi. Bu değişkenlerin değerleri Prices() yönteminde güncellenir. Bu değişkenler arabellek olarak davranır.
Ardından, m_price_module parametresi bildirilir. İlk fiyat modülünün indeksini CExpertSignal içinde bildirilen m_filters dizisinde saklar. Bu dizi, dahil edilen sinyal modüllerinin işaretçilerini içerir. Standart modüllere (filtreler) yönelik işaretçiler, dizinin başında saklanır. Ardından m_price_module indeksinden başlayarak fiyat modülleri gelir. Göstergelerin ve zaman serilerinin başlatma yöntemlerinin değiştirilmesi gerekliliğinden kaçınmak için her şeyin tek bir dizide saklanmasına karar verildi. Ayrıca, bir dizi üzerinden 64 modül içerme olasılığı vardır ve genellikle yeterlidir.
Ayrıca, korunan veri üyelerinin değerlerini elde etmek için CExpertSignalAdvanced sınıfında yardımcı yöntemler bildirildi. Adları get ile başlar (sınıf bildirimine bakın).
3.1.1. Kurucu
kurucu CExpertSignalAdvanced, sınıf içinde bildirilen değişkenleri başlatır:
CExpertSignalAdvanced::CExpertSignalAdvanced() { m_order_open_long=EMPTY_VALUE; m_order_stop_long=EMPTY_VALUE; m_order_take_long=EMPTY_VALUE; m_order_expiration_long=0; m_order_open_short=EMPTY_VALUE; m_order_stop_short=EMPTY_VALUE; m_order_take_short=EMPTY_VALUE; m_order_expiration_short=0; m_price_module=-1; }
3.1.2. CalcPriceModuleIndex()
CalcPriceModuleIndex() yöntemi, m_price_module mevcut dizi öğeleri sayısını, aşağıdaki eklenen modülün dizinine eşit olarak atar. Bu yöntem, ilk fiyat modülünü eklemeden önce çağrılır. İşlev gövdesi sınıf bildirimindedir.
virtual void CalcPriceModuleIndex() {m_price_module=m_filters.Total();}
3.1.3. CheckOpenLong(...) ve CheckOpenShort(...)
CheckOpenLong(...) yöntemi, CExpert sınıfı örneğinden çağrılır ve aşağıda açıklandığı gibi çalışır:
- Dahil edilen fiyat modüllerini kontrol edin. Hiçbiri yoksa üst sınıfın isimsiz yöntemini çağırın;
- Direction() yönteminden ağırlıklı ortalama tahmin (yön) alın;
- Yönü EMPTY_VALUE ile ve m_threshold_open eşik değerini karşılaştırarak giriş koşullarının karşılanıp karşılanmadığını doğrulayın;
- Talimat parametrelerinin değerlerini Prices() yöntemiyle yenileyin ve OpenLongParams(...) işleviyle Expert'e iletin. Bu işlevin sonucunu kaydedin;
- Kaydedilen sonucu döndürün.
bool CExpertSignalAdvanced::CheckOpenLong(double &price,double &sl,double &tp,datetime &expiration) { //--- if price modules were not found, call the method of the basic class CExpertSignal if(m_price_module<0) return(CExpertSignal::CheckOpenLong(price,sl,tp,expiration)); bool result =false; double direction=Direction(); //--- prohibitive signal if(direction==EMPTY_VALUE) return(false); //--- check for exceeding the threshold if(direction>=m_threshold_open) { Prices(); result=OpenLongParams(price,sl,tp,expiration);//there's a signal if m_order_open_long!=EMPTY_VALUE } //--- return the result return(result); }
CheckOpenShort(...) aynı çalışma prensibine sahiptir ve aynı şekilde kullanılır, bu yüzden dikkate almayacağız.
3.1.4 Direction()
Direction() yöntemi, filtreleri sorgular ve ağırlıklı ortalama tahmini hesaplar. Bu yöntem, döngüde m_filters dizisinin tüm öğelerine değil, yalnızca 0'dan m_price_module modülüne kadar değişen bir indekse sahip olanlara atıfta bulunmamız dışında, üst sınıf CExpertSignal sinyalinin adsız yöntemine çok benzer. Geri kalan her şey CExpertSignal::Direction() yönüne benzer.
double CExpertSignalAdvanced::Direction(void) { long mask; double direction; double result=m_weight*(LongCondition()-ShortCondition()); int number=(result==0.0)? 0 : 1; // number of queried modules //--- loop by filters for(int i=0;i<m_price_module;i++) { //--- mask for bitmaps (variables, containing flags) mask=((long)1)<<i; //--- checking for a flag of ignoring a filter signal if((m_ignore&mask)!=0) continue; CExpertSignal *filter=m_filters.At(i); //--- checking for a pointer if(filter==NULL) continue; direction=filter.Direction(); //--- prohibitive signal if(direction==EMPTY_VALUE) return(EMPTY_VALUE); if((m_invert&mask)!=0) result-=direction; else result+=direction; number++; } //--- averaging the sum of weighted forecasts if(number!=0) result/=number; //--- return the result return(result); }
3.1.5. Fiyatlar()
Prices() yöntemi, m_price_module dizininden sonuna kadar m_filters dizisinin ikinci kısmı üzerinde yinelenir. Bu, fiyat modüllerini sorgular ve OpenLongParams(...) ve OpenShortParams(...) işlevleriyle sınıf değişkenlerinin değerlerini yeniler. Döngüden önce parametre değerleri temizlenir.
Döngü sırasında, mevcut fiyat modülünün (m_weight) ağırlığı, daha önce sorgulanan ve değerleri sağlayan modüllerden daha büyükse parametre değerlerinin üzerine yazılır. Sonuç olarak ya boş parametreler (hiçbir şey bulunamadıysa) ya da bir yöntem çağrıldığında mevcut en iyi ağırlığa sahip parametreler bırakılır.
double CExpertSignalAdvanced::Prices(void) { m_order_open_long=EMPTY_VALUE; m_order_stop_long=EMPTY_VALUE; m_order_take_long=EMPTY_VALUE; m_order_expiration_long=0; m_order_open_short=EMPTY_VALUE; m_order_stop_short=EMPTY_VALUE; m_order_take_short=EMPTY_VALUE; m_order_expiration_short=0; int total=m_filters.Total(); double last_weight_long=0; double last_weight_short=0; //--- cycle for price modules for(int i=m_price_module;i<total;i++) { CExpertSignalAdvanced *prm=m_filters.At(i); if(prm==NULL) continue; //--- ignore the current module if it has returned EMPTY_VALUE if(prm.Prices()==EMPTY_VALUE)continue; double weight=prm.getWeight(); if(weight==0.0)continue; //--- select non-empty values from modules with the greatest weight if(weight>last_weight_long && prm.getExpLong()>TimeCurrent()) if(prm.OpenLongParams(m_order_open_long,m_order_stop_long,m_order_take_long,m_order_expiration_long)) last_weight_long=weight; if(weight>last_weight_short && prm.getExpShort()>TimeCurrent()) if(prm.OpenShortParams(m_order_open_short,m_order_stop_short,m_order_take_short,m_order_expiration_short)) last_weight_short=weight; } return(0); }
3.1.6. OpenLongParams(...) ve OpenShortParams(...)
CExpertSignalAdvanced sınıfı içinde, OpenLongParams(...) yöntemi, sınıf değişkenlerinden referansla satın alınacak talimatın parametre değerlerini giriş parametrelerine iletir.
Bu yöntemin üst sınıftaki rolü biraz farklıydı. Bu, piyasa fiyatına ve ana sinyalde belirtilen girintilere dayalı olarak gerekli parametreleri hesaplıyordu. Şimdi bu sadece hazır parametreleri iletir. Açılış fiyatı doğruysa (EMPTY_VALUE değerine eşit değilse) yöntem true, aksi takdirde false döndürür.
bool CExpertSignalAdvanced::OpenLongParams(double &price,double &sl,double &tp,datetime &expiration) { if(m_order_open_long!=EMPTY_VALUE) { price=m_order_open_long; sl=m_order_stop_long; tp=m_order_take_long; expiration=m_order_expiration_long; return(true); } return(false); }
Çalışma prensibi aynı olduğu ve benzer şekilde kullanıldığı için OpenShortParams(...) konusunu ele almayacağız.
3.1.7. CheckUpdateOrderLong(...) ve CheckUpdateOrderShort(...)
CheckUpdateOrderLong(...) ve CheckUpdateOrderShort(...) yöntemlerine CExpertAdvanced sınıfı çağrılır. Halihazırda verilmiş bekleyen talimatları son fiyat seviyelerine göre güncellemek için kullanılırlar.
CheckUpdateOrderLong(...) yöntemini daha yakından inceleyeceğiz. Fiyatlar(...) yöntemi çağrılırken ilk olarak fiyat seviyeleri güncellenir, ardından olası değişiklik hatalarını dışlamak için veri güncellemeleri için bir kontrol yapılır. Son olarak güncellenmiş verileri geçirmek ve sonucu döndürmek için OpenLongParams(...) yöntemi çağrılır.
bool CExpertSignalAdvanced::CheckUpdateOrderLong(COrderInfo *order_ptr,double &open,double &sl,double &tp,datetime &ex) { Prices(); //update prices //--- check for changes double point=m_symbol.Point(); if( MathAbs(order_ptr.PriceOpen() - m_order_open_long)>point || MathAbs(order_ptr.StopLoss() - m_order_stop_long)>point || MathAbs(order_ptr.TakeProfit()- m_order_take_long)>point || order_ptr.TimeExpiration()!=m_order_expiration_long) return(OpenLongParams(open,sl,tp,ex)); //--- update is not required return (false); }
CheckUpdateOrderShort(...) benzer şekilde çalıştığı ve aynı şekilde uygulandığı için dikkate alınmayacaktır.
3.2. CExpertAdvanced
Expert sınıfındaki değişiklikler, yalnızca ana sinyaldeki fiyatlara ilişkin güncellenmiş verilere göre önceden verilmiş talimatların değiştirilmesiyle ilgilidir. CExpertAdvanced sınıf bildirimi aşağıda sunulmuştur.
class CExpertAdvanced : public CExpert { protected: virtual bool CheckTrailingOrderLong(); virtual bool CheckTrailingOrderShort(); virtual bool UpdateOrder(double price,double sl,double tp,datetime ex); public: CExpertAdvanced(); ~CExpertAdvanced(); };
Gördüğümüz gibi yöntemler azdır, yapıcı ve oluşturucu boştur.
3.2.1. CheckTrailingOrderLong() ve CheckTrailingOrderShort()
CheckTrailingOrderLong() yöntemi, temel sınıfın adsız bir yöntemini geçersiz kılar ve sırayı değiştirme gerekliliğini anlamak için ana sinyalin CheckUpdateOrderLong(...) yöntemini çağırır. Değişiklik gerekiyorsa UpdateOrder(...) yöntemi çağrılır ve sonuç döndürülür.
bool CExpertAdvanced::CheckTrailingOrderLong(void) { CExpertSignalAdvanced *signal_ptr=m_signal; //--- check for the opportunity to modify the order to buy double price,sl,tp; datetime ex; if(signal_ptr.CheckUpdateOrderLong(GetPointer(m_order),price,sl,tp,ex)) return(UpdateOrder(price,sl,tp,ex)); //--- return with no actions taken return(false); }
CheckTrailingOrderShort() yöntemi benzerdir ve aynı şekilde kullanılır.
3.2.2. UpdateOrder()
UpdateOrder() işlevi, ilgili fiyatın kontrolüyle başlar (EMPTY_VALUE değil). Yoksa talimat silinir, aksi halde alınan parametrelere göre talimat değiştirilir.
bool CExpertAdvanced::UpdateOrder(double price,double sl,double tp,datetime ex) { ulong ticket=m_order.Ticket(); if(price==EMPTY_VALUE) return(m_trade.OrderDelete(ticket)); //--- modify the order, return the result return(m_trade.OrderModify(ticket,price,sl,tp,m_order.TypeTime(),ex)); }
Standart sınıflar devralanların geliştirilmesi tamamlandı.
4. Fiyat Modüllerinin Geliştirilmesi
Hesaplanan seviyelerde talimatları ve Zararı Durdur işlemini veren Expert'ler oluşturmak için zaten temelimiz var. Kesin olmak gerekirse fiyat seviyeleri ile çalışmak için kullanıma hazır sınıflarımız mevcut. Artık sadece bu seviyeleri oluşturacak modüller yazılmaya bırakıldı.
Fiyat modülleri geliştirme süreci, alım satım sinyalleri modülleri yazmaya benzer. Aralarındaki tek fark, sinyal modüllerinde olduğu gibi LongCondition(), ShortCondition() veya Yön() değil, modül içindeki fiyat güncellemesinden sorumlu yöntem olan Fiyatlar() modülünün geçersiz kılınması gerektiğidir. İdeal olarak, okuyucunun sinyal modüllerinin gelişimi hakkında net bir fikri olmalıdır. "6 Adımda Kendi İşlem Robotunuzu Oluşturun!" ve "Özel Göstergeye Dayalı İşlem Sinyali Oluşturucu" makaleleri bu konuda faydalı olabilir.
Birkaç fiyat modülünün kodu, bu konuya bir örnek teşkil edecek.
4.1. "Delta ZigZag" Göstergesine Dayalı Fiyat Modülü
Delta ZigZag göstergesi, belirtilen sayıda en son tepe noktasına göre seviyeler çizer. Fiyat bu seviyeleri geçerse olası bir trend dönüşü anlamına gelir.
Fiyat modülünün amacı, gösterge tamponundan giriş seviyesini almak, Zararı Durdur'u vermek için en yakın yerel ekstremi bulmak, Zararı Durdur'u ayarlarda belirtilen katsayı ile çarparak Kar Al'ı hesaplamaktır.
Şek. 3. Örnek olarak satın alma talimatı kullanılarak Delta ZigZag göstergesinde fiyat modülü işleminin gösterimi
Şek. 3. fiyat modülü tarafından üretilen seviyeleri temsil etmektedir. Talimat tetiklenmeden önce, Zarar Durdur ve Kar Al işlemleri, minimum güncellemelerini takiben buna göre değişir.
4.1.1. Modül Tanımlayıcı
// wizard description start //+------------------------------------------------------------------+ //| Description of the class | //| Title=DeltaZZ Price Module | //| Type=SignalAdvanced | //| Name=DeltaZZ Price Module | //| ShortName=DeltaZZ_PM | //| Class=CPriceDeltaZZ | //| Page=not used | //| Parameter=setAppPrice,int,1, Applied price: 0 - Close, 1 - H/L | //| Parameter=setRevMode,int,0, Reversal mode: 0 - Pips, 1 - Percent | //| Parameter=setPips,int,300,Reverse in pips | //| Parameter=setPercent,double,0.5,Reverse in percent | //| Parameter=setLevels,int,2,Peaks number | //| Parameter=setTpRatio,double,1.6,TP:SL ratio | //| Parameter=setExpBars,int,10,Expiration after bars number | //+------------------------------------------------------------------+ // wizard description end
Tanımlayıcıdaki ilk beş parametre, kullanımdaki göstergeyi ayarlamak için gereklidir. Ardından, mevcut fiyat modülünden talimatlar için çubuklardaki Zarar Durdur ve son kullanma süresine göre Kar Al hesaplama katsayısı gelir.
4.1.2. Sınıf Beyanı
class CPriceDeltaZZ : public CExpertSignalAdvanced { protected: CiCustom m_deltazz; //object of the DeltaZZ indicator //--- module settings int m_app_price; int m_rev_mode; int m_pips; double m_percent; int m_levels; double m_tp_ratio; //tp:sl ratio int m_exp_bars; //lifetime of the orders in bars //--- method of indicator initialization bool InitDeltaZZ(CIndicators *indicators); //--- helper methods datetime calcExpiration() { return(TimeCurrent()+m_exp_bars*PeriodSeconds(m_period)); } double getBuySL(); //function for searching latest minimum of ZZ for buy SL double getSellSL(); //function for searching latest maximum of ZZ for sell SL public: CPriceDeltaZZ(); ~CPriceDeltaZZ(); //--- methods of changing module settings void setAppPrice(int ap) { m_app_price=ap; } void setRevMode(int rm) { m_rev_mode=rm; } void setPips(int pips) { m_pips=pips; } void setPercent(double perc) { m_percent=perc; } void setLevels(int rnum) { m_levels=rnum; } void setTpRatio(double tpr) { m_tp_ratio=tpr; } void setExpBars(int bars) { m_exp_bars=bars;} //--- method of checking correctness of settings virtual bool ValidationSettings(void); //--- method of creating indicators virtual bool InitIndicators(CIndicators *indicators); //--- main method of price module updating the output data virtual double Prices(); };
Korumalı veri - CiCustom türünün göstergesinin nesnesi ve tanımlayıcıda belirtilen türlere göre parametreler modülde bildirilir.
4.1.3. Kurucu
Kurucu, sınıf parametrelerini varsayılan değerlerle başlatır. Daha sonra, Expert'in giriş parametrelerine göre modül ana sinyale dahil edildiğinde bu değerler bir kez daha başlatılır.
CPriceDeltaZZ::CPriceDeltaZZ() : m_app_price(1), m_rev_mode(0), m_pips(300), m_percent(0.5), m_levels(2), m_tp_ratio(1), m_exp_bars(10) { }
4.1.4. ValidationSettings()
ValidationSettings(), giriş parametrelerini kontrol etmek için önemli bir yöntemdir. Modül parametrelerinin değerleri geçersizse sonuç false döndürülür ve günlükte bir hata mesajı yazdırılır.
bool CPriceDeltaZZ::ValidationSettings(void) { //--- checking for settings of additional filters if(!CExpertSignal::ValidationSettings()) return(false); //--- initial data check if(m_app_price<0 || m_app_price>1) { printf(__FUNCTION__+": Applied price must be 0 or 1"); return(false); } if(m_rev_mode<0 || m_rev_mode>1) { printf(__FUNCTION__+": Reversal mode must be 0 or 1"); return(false); } if(m_pips<10) { printf(__FUNCTION__+": Number of pips in a ray must be at least 10"); return(false); } if(m_percent<=0) { printf(__FUNCTION__+": Percent must be greater than 0"); return(false); } if(m_levels<1) { printf(__FUNCTION__+": Ray Number must be at least 1"); return(false); } if(m_tp_ratio<=0) { printf(__FUNCTION__+": TP Ratio must be greater than zero"); return(false); } if(m_exp_bars<0) { printf(__FUNCTION__+": Expiration must be zero or positive value"); return(false); } //--- parameter check passed return(true); }
4.1.5. InitIndicators(...)
InitIndicators(...) yöntemi, temel sınıfın adsız bir yöntemini çağırır ve geçerli modülün göstergesini InitDeltaZZ(...) yöntemiyle başlatır.
bool CPriceDeltaZZ::InitIndicators(CIndicators *indicators) { //--- initialization of indicator filters if(!CExpertSignal::InitIndicators(indicators)) return(false); //--- creating and initializing of custom indicator if(!InitDeltaZZ(indicators)) return(false); //--- success return(true); }
4.1.6. InitDeltaZZ(...)
InitDeltaZZ(...) yöntemi, özel gösterge nesnesini koleksiyona ekler ve yeni gösterge "Delta ZigZag" oluşturur.
bool CPriceDeltaZZ::InitDeltaZZ(CIndicators *indicators) { //--- adds to collection if(!indicators.Add(GetPointer(m_deltazz))) { printf(__FUNCTION__+": error adding object"); return(false); } //--- specifies indicator parameters MqlParam parameters[6]; //--- parameters[0].type=TYPE_STRING; parameters[0].string_value="deltazigzag.ex5"; parameters[1].type=TYPE_INT; parameters[1].integer_value=m_app_price; parameters[2].type=TYPE_INT; parameters[2].integer_value=m_rev_mode; parameters[3].type=TYPE_INT; parameters[3].integer_value=m_pips; parameters[4].type=TYPE_DOUBLE; parameters[4].double_value=m_percent; parameters[5].type=TYPE_INT; parameters[5].integer_value=m_levels; //--- object initialization if(!m_deltazz.Create(m_symbol.Name(),m_period,IND_CUSTOM,6,parameters)) { printf(__FUNCTION__+": error initializing object"); return(false); } //--- number of the indicator buffers if(!m_deltazz.NumBuffers(5)) return(false); //--- ок return(true); }
ValidationSettings(), InitDeltaZZ(...) ve InitIndicators(...) yöntemlerinin başarıyla tamamlanmasından sonra modül başlatılır ve kullanıma hazırdır.
4.1.7. Fiyatlar()
Bu yöntem, fiyat modülü için temeldir. Burası, talimat parametrelerinin güncellendiği yerdir. Değerleri ana sinyale iletilir. Bu yöntem, çift türünün işlem sonucunu döndürür. Bu, esas olarak gelecekteki gelişme için uygulandı. Prices() yönteminin sonucu, ana sinyalin uygun şekilde işleyebilmesi için bazı özel durumları ve olayları kodlayabilir. Şu anda yalnızca döndürülen EMPTY_VALUE değerinin işlenmesi amaçlanmaktadır. Bu sonucu aldıktan sonra, ana sinyal modül tarafından önerilen parametreleri görmezden gelecektir.
Bu modüldeki Prices() yönteminin çalışma algoritması:
- Sırasıyla alım ve satım için gösterge arabellekleri 3 ve 4'ten talimatların açılış fiyatlarını alın;
- Talimatların son parametrelerini sıfırlayın;
- Satın almak için fiyatı kontrol edin. Varsa GetBuySL() yöntemi ile Zararı Durdur seviyesini belirleyin, Zararı Durdur değeri ve açılış fiyatından Kar Al seviyesini hesaplayın ve talimatın sona erme süresini hesaplayın;
- Satmak için fiyatı kontrol edin. Tespit edilirse getSellSL() yöntemi ile Zararı Durdur seviyesini bulun, Zarar Durdur değeri ve açılış fiyatına göre Kar Al seviyesini hesaplayın ve talimatın sona erme süresini hesaplayın;
- Çıkış yapın.
double CPriceDeltaZZ::Prices(void) { double openbuy =m_deltazz.GetData(3,0);//receive the last value from buffer 3 double opensell=m_deltazz.GetData(4,0);//receive the last value from buffer 4 //--- clear parameter values m_order_open_long=EMPTY_VALUE; m_order_stop_long=EMPTY_VALUE; m_order_take_long=EMPTY_VALUE; m_order_expiration_long=0; m_order_open_short=EMPTY_VALUE; m_order_stop_short=EMPTY_VALUE; m_order_take_short=EMPTY_VALUE; m_order_expiration_short=0; int digits=m_symbol.Digits(); //--- check for the prices to buy if(openbuy>0)//if buffer 3 is not empty { m_order_open_long=NormalizeDouble(openbuy,digits); m_order_stop_long=NormalizeDouble(getBuySL(),digits); m_order_take_long=NormalizeDouble(m_order_open_long + m_tp_ratio*(m_order_open_long - m_order_stop_long),digits); m_order_expiration_long=calcExpiration(); } //--- check for the prices to sell if(opensell>0)//if buffer 4 is not empty { m_order_open_short=NormalizeDouble(opensell,digits); m_order_stop_short=NormalizeDouble(getSellSL(),digits); m_order_take_short=NormalizeDouble(m_order_open_short - m_tp_ratio*(m_order_stop_short - m_order_open_short),digits); m_order_expiration_short=calcExpiration(); } return(0); }
4.1.8. getBuySL() ve getSellSL()
getBuySL() ve getSellSL() yöntemleri, Zararı Durdur'u yerleştirmek için ilgili yerel minimumları ve maksimumları arar. İlgili bir arabellekte – son sıfır olmayan değer, her yöntemde son yerel ekstremin fiyat düzeyi aranır.
double CPriceDeltaZZ::getBuySL(void) { int i=0; double sl=0.0; while(sl==0.0) { sl=m_deltazz.GetData(0,i); i++; } return(sl); } double CPriceDeltaZZ::getSellSL(void) { int i=0; double sl=0.0; while(sl==0.0) { sl=m_deltazz.GetData(1,i); i++; } return(sl); }
4.2. İç Çubuğa Dayalı Fiyat Modülü
İç çubuk, Fiyat işlemi olarak adlandırılan hiçbir gösterge içermeyen alım satımda yaygın olarak kullanılan formasyonlar veya kalıplardan biridir. Bir iç çubuk, önceki çubuğun uç noktaları içinde Yüksek ve Düşük olan bir çubuktur. Bir iç çubuk, konsolidasyonun başladığını veya fiyat hareketinin tersine çevrilme olasılığını gösterir.
Şekil 4'te iç çubuklar kırmızı elipslerin içindedir. Bir iç çubuk tespit edildiğinde, fiyat modülü, iç çubuğun önündeki çubuğun uç noktasında buystop ve sellstop talimatlarının açılış fiyatlarını üretir.
Açılış fiyatları, karşıt talimatlar için Zarar Durdur seviyeleridir. Kar Al, yukarıda tartışılan modüldekiyle aynı şekilde hesaplanır - Zarar Durdurma seviyesi ayarlarında belirtilen katsayı ile çarpılarak. Açılış fiyatları ve Zarar Durdurma kırmızı yatay çizgilerle, Kar Al yeşil olanlarla işaretlenmiştir.
Şek. 4. Fiyat modülünün iç çubuklarının ve seviyelerinin gösterimi
Şek. 4'te, trend yaklaştığı için satılacak talimatlar verilmemektedir. Bununla birlikte, fiyat modülü her iki yönde de giriş seviyeleri oluşturur. Bazı Kar Al seviyeleri planın dışındadır.
Önceki modülden farklı olarak, bu modülün algoritması basittir ve göstergelerin başlatılmasını gerektirmez. Modülde çok az kod vardır; bu, aşağıda tam olarak sunulmuştur. Yine de her işlevi ayrı ayrı analiz etmeyeceğiz.
#include <Expert\ExpertSignalAdvanced.mqh> // wizard description start //+------------------------------------------------------------------+ //| Description of the class | //| Title=Inside Bar Price Module | //| Type=SignalAdvanced | //| Name=Inside Bar Price Module | //| ShortName=IB_PM | //| Class=CPriceInsideBar | //| Page=not used | //| Parameter=setTpRatio,double,2,TP:SL ratio | //| Parameter=setExpBars,int,10,Expiration after bars number | //| Parameter=setOrderOffset,int,5,Offset for open and stop loss | //+------------------------------------------------------------------+ // wizard description end //+------------------------------------------------------------------+ //| Class CPriceInsideBar | //| Purpose: Class of the generator of price levels for orders based | //| on the "inside bar" pattern. | //| Is derived from the CExpertSignalAdvanced class. | //+------------------------------------------------------------------+ class CPriceInsideBar : public CExpertSignalAdvanced { protected: double m_tp_ratio; //tp:sl ratio int m_exp_bars; //lifetime of the orders in bars double m_order_offset; //shift of the opening and Stop Loss levels datetime calcExpiration() { return(TimeCurrent()+m_exp_bars*PeriodSeconds(m_period)); } public: CPriceInsideBar(); ~CPriceInsideBar(); void setTpRatio(double ratio){ m_tp_ratio=ratio; } void setExpBars(int bars) { m_exp_bars=bars;} void setOrderOffset(int pips){ m_order_offset=m_symbol.Point()*pips;} bool ValidationSettings(); double Prices(); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CPriceInsideBar::CPriceInsideBar() { } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CPriceInsideBar::~CPriceInsideBar() { } //+------------------------------------------------------------------+ //| Validation of protected settings | //+------------------------------------------------------------------+ bool CPriceInsideBar::ValidationSettings(void) { //--- verification of the filter parameters if(!CExpertSignal::ValidationSettings()) return(false); //--- initial data check if(m_tp_ratio<=0) { printf(__FUNCTION__+": TP Ratio must be greater than zero"); return(false); } if(m_exp_bars<0) { printf(__FUNCTION__+": Expiration must be zero or positive value"); return(false); } //--- check passed return(true); } //+------------------------------------------------------------------+ //| Price levels refreshing | //+------------------------------------------------------------------+ double CPriceInsideBar::Prices(void) { double h[2],l[2]; if(CopyHigh(m_symbol.Name(),m_period,1,2,h)!=2 || CopyLow(m_symbol.Name(),m_period,1,2,l)!=2) return(EMPTY_VALUE); //--- check for inside bar if(h[0] >= h[1] && l[0] <= l[1]) { m_order_open_long=h[0]+m_order_offset; m_order_stop_long=l[0]-m_order_offset; m_order_take_long=m_order_open_long+(m_order_open_long-m_order_stop_long)*m_tp_ratio; m_order_expiration_long=calcExpiration(); m_order_open_short=m_order_stop_long; m_order_stop_short=m_order_open_long; m_order_take_short=m_order_open_short-(m_order_stop_short-m_order_open_short)*m_tp_ratio; m_order_expiration_short=m_order_expiration_long; return(0); } return(EMPTY_VALUE); } //+------------------------------------------------------------------+
Bu modülün Prices() yönteminde, EMPTY_VALUE sonucunun dönüşü, ana sinyale uygun fiyat seviyelerinin olmadığını göstermek için kullanılır.
4.3. Dış Çubuğa Dayalı Fiyat Modülü
Dış çubuk, "emilim" olarak da adlandırılan bir başka popüler Fiyat Hareketi formasyonudur. Dış çubuğun Yüksek ve Düşük değeri bir önceki çubuğun Yüksek ve Düşük değeri ile üst üste binmesi nedeniyle çağrılır. Bir dış çubuğun ortaya çıkması, volatilite artışının ardından yönlendirilmiş bir fiyat hareketinin bir göstergesidir.
Şek. 5'te dış çubuklar kırmızı elipslerle işaretlenmiştir. Fiyat modülü, bir dış çubuğu tespit ettikten sonra, uç noktasında buystop ve sellstop talimatlarının açılış fiyatlarını üretir.
Açılış fiyatları, karşıt talimatlar için Zarar Durdur seviyeleridir. Kar Al, yukarıda tartışılan modüldekiyle aynı şekilde hesaplanır - Zarar Durdurma seviyesi ayarlarında belirtilen katsayı ile çarpılarak. Açılış fiyatları ve Zarar Durdurma kırmızı yatay çizgilerle, Kar Al yeşil olanlarla işaretlenmiştir.
Şek. 5. Dış çubukların ve fiyat modülü seviyelerinin gösterimi
Şekil 5'te dış çubuklar kırmızı elipslerle işaretlenmiştir. Yatay çizgiler, fiyat modülü tarafından oluşturulan bekleyen talimatların açılış fiyatlarını yansıtır.
Bu durumda düşüş trendi olduğu için sadece satış talimatları açılır. Bu modülün çalışması temelde bir öncekine benzer. Kodu arasındaki tek fark, yalnızca Prices() yöntemidir, diğer parçalar tamamen aynıdır ve aynı adlara sahiptir. Aşağıda Prices() kodu yer almaktadır.
double CPriceOutsideBar::Prices(void) { double h[2],l[2]; if(CopyHigh(m_symbol.Name(),m_period,1,2,h)!=2 || CopyLow(m_symbol.Name(),m_period,1,2,l)!=2) return(EMPTY_VALUE); //--- check of outside bar if(h[0] <= h[1] && l[0] >= l[1]) { m_order_open_long=h[1]+m_order_offset; m_order_stop_long=l[1]-m_order_offset; m_order_take_long=m_order_open_long+(m_order_open_long-m_order_stop_long)*m_tp_ratio; m_order_expiration_long=calcExpiration(); m_order_open_short=m_order_stop_long; m_order_stop_short=m_order_open_long; m_order_take_short=m_order_open_short-(m_order_stop_short-m_order_open_short)*m_tp_ratio; m_order_expiration_short=m_order_expiration_long; return(0); } return(EMPTY_VALUE); }
4.4. Modül Performans Testi
Bir sonraki bölümde, tek bir Expert'te bireysel ve birleşik çalışmalarını kontrol etmek ve sistemin tasarlandığı gibi çalıştığından emin olmak için üç modül örneği test edilir. Sonuç olarak, dört Expert oluşturulur. H12 zaman dilimi üzerinde çalışan Awesome Oscillator göstergesine dayalı alım satım sinyali modülü, oluşturulan Expert'lerin her birinde bir filtre olarak kullanılır. Fiyat modülleri H6 üzerinde çalışıyor.
Para yönetimi: sabit lot ve Takip Eden Durdur işlemi kullanılmaz. Tüm testler, 2013.01.01'den 2014.06.01'e kadar olan süre için MetaQuotes-Demo sunucusunun demo hesabından EURUSD kotasyonları üzerinde gerçekleştirilir. Terminal sürümü: 5.00, yapı 965 (27 Haziran 2014).
Kısa tutmak için, test sonuçları yalnızca denge grafikleriyle temsil edilir. Her özel durumda Expert'in davranışını elde etmek için yeterlidir.
4.4.1. Modülü Delta ZigZag Göstergesine Dayalı Test Etme
Şek. 6. "Delta ZigZag" göstergesine dayalı fiyat modülünün test edilmesinde bakiye taslağı
4.4.2. Modülü "İç Çubuk" Formasyonuna Dayalı Test Etme
Şek. 7. İç çubuğa dayalı fiyat modülünün test edilmesinde bakiye taslağı
Şekil 7'ye bakıldığında, bu aşamadaki testlerin amacının kazanan bir strateji elde etmek değil, kod performansını kontrol etmek olduğu unutulmamalıdır.
4.4.3. Modülü "Dış Çubuk" Formasyonuna Dayalı Test Etme
Şek. 8. Dış çubuğa dayalı fiyat modülünün test edilmesinde bakiye taslağı
4.4.4. Geliştirilmiş Fiyat Modüllerinin Ortak Çalışmasının Test Edilmesi
Önceki test sonuçları dikkate alındığında, DeltaZigZag tabanlı fiyat modülleri, iç çubuk ve dış çubuk sırasıyla 1, 0,5 ve 0,7 ağırlık katsayıları aldı. Ağırlık katsayıları, fiyat modüllerinin önceliklerini tanımlar.
Şek. 9. Üç fiyat modülüne sahip Expert'in test edilmesinde bakiye taslağı
Testin her aşamasında, fiyat taslakları üzerinde gerçekleştirilen tüm işlemler dikkatlice analiz edildi. Strateji hataları ve sapmaları ortaya çıkmadı. Önerilen tüm programlar bu makaleye eklenmiştir ve bunları kendiniz test edebilirsiniz.
5. Kullanım Talimatı
Üç fiyat modülü ve bir filtre olarak Awesome Oscillator ile Expert örneğinde geliştirilen uzantıyı kullanarak Expert geliştirmenin aşamalarını ele alacağız.
Üretim başlamadan önce, "CExpertAdvanced.mqh" ve "CExpertSignalAdvanced.mqh" başlık dosyalarının MetaTrader 5 terminalinin kataloğunda MQL5/Include/Expert klasöründe ve fiyat modüllerinin dosyalarının MQL5/Include/Expert/MySignal klasöründe olduğundan emin olun. Expert'i başlatmadan önce, derlenmiş göstergelerin MQL5/Indicators klasöründe olduğundan emin olun. Bu durumda "DeltaZigZag.ex5" dosyasıdır. Ekli arşivde tüm dosyalar yerlerindedir. Tek yapmanız gereken bu arşivi MetaTrader 5 terminali ile bir klasöre açmak ve birleştirme kataloglarını onaylamaktır.
5.1. Expert Oluşturma
Expert oluşturmayı başlatmak için MetaEditor'da "Dosya"->"Yeni" öğesini seçin.
Şek. 10. MQL5 Sihirbazını kullanarak yeni bir Expert oluşturma
Yeni pencerede «Expert Advisor (oluştur)" seçeneğini belirleyin ve ardından "İleri" öğesine basın.
Şek. 11. MQL5 Sihirbazını Kullanarak Bir Uzman Oluşturma
Adı belirtebileceğiniz bir pencere açılacaktır. Bu özel örnekte, Expert'in adı "TEST_EA_AO_DZZ_IB_OB" şeklindedir, Symbol ve TimeFrame parametrelerinin varsayılan değerleri vardır. Ardından "İleri" öğesine tıklayın.
Şek. 12. Expert Advisor'ın genel özellikleri
Açılan pencerede "Ekle" tuşuna basarak modülleri tek tek ekleyin. Tüm süreç aşağıda sunulmuştur.
LÜTFEN UNUTMAYIN! Modülleri eklerken, önce tüm sinyal modüllerini (devralanlar CExpertSignal) ve ardından fiyat modüllerini (devralanlar CExpertSignalAdvanced) dahil edin. Bu modülleri dahil etme talimatını bozmanın sonucu tahmin edilemez olacaktır.
Bu nedenle, Awesome Oscillator'dan gelen sinyal modüllerini dahil ederek başlıyoruz. Bu örnekteki tek filtredir.
Şek. 13. Awesome Oscillator'den gelen sinyal modülünü içerir
Tüm sinyal modülleri dahil edildikten sonra gerekli fiyat modüllerini rastgele bir sırayla dahil edin. Bu örnekte bunlardan üç tane mevcut.
Şek. 14. DeltaZZ Fiyat Modülünden gelen sinyal modülünü içerir
Şek. 15. İç Çubuk Fiyat Modülünden gelen sinyal modülünü içerir
Şek. 16. Dış Çubuk Fiyat Modülünden gelen sinyal modülünü içerir
Tüm modüller eklendikten sonra pencere aşağıdaki gibi görünecektir:
Şek. 17. Dahil edilen alım satım sinyalleri modüllerinin listesi
Fiyat modülünün "Ağırlık" parametresinin değeri önceliğini tanımlar.
"İleri" düğmesine basıldıktan sonra Sihirbaz, para yönetimi modüllerini ve İzleyen Durdurma modüllerini seçmenizi önerir. Bunlardan birini seçin veya "İleri" veya "Hazır" düğmesine basarak olduğu gibi bırakın.
"Hazır" düğmesine basıldığında, oluşturulan Advisor kodunu alacağız.
5.2. Oluşturulan Kodu Düzenleme
Böylece, kodumuzu elde ettik.
1. En başta dizeyi bulun ve
#include <Expert\Expert.mqh>
şöyle görünecek şekilde düzenleyin
#include <Expert\ExpertAdvanced.mqh>
Geliştirilen sınıfların dosyalarının eklenmesi gerekir.
2. Sonra dizeyi bulun
CExpert ExtExpert;
ve değiştirin
CExpertAdvanced ExtExpert;
Bu, gerekli işlevlere sahip alt öğe için Expert standart sınıfını değiştirecektir.
3. Şimdi dizeyi bulun
CExpertSignal *signal=new CExpertSignal;
ve değiştirin
CExpertSignalAdvanced *signal=new CExpertSignalAdvanced;
Bu, gerekli işlevlerle alt öğeden gelen ana sinyalin standart sınıfını değiştirmenin yoludur.
4. Ana sinyalin m_filters dizisine ilk fiyat modülünün eklenmesini uygulayan dizeyi bulun. Bu örnekte şöyle görünür:
signal.AddFilter(filter1);
Bundan önce dizeyi ekliyoruz
signal.CalcPriceModuleIndex();
Bu, ana sinyalin m_filters dizisinde hangi indekse kadar sinyal modülü işaretçileri olduğunu ve hangi fiyat modülü işaretçilerinin bulunduğunu tanıması için gereklidir.
Belirtilen dizeyi eklemek için doğru konumu bulmak zor olabilir. Referans noktası olarak "filtre" kelimesinden sonraki sayıyı kullanın. Aramayı basitleştirecek ve doğru pozisyonu kaçırmamayı sağlayacaktır. MQL5 Sihirbazı, modülleri otomatik olarak talimatlarına dahil etti. İlk modül filter0, ikincisi filter1, üçüncüsü – filter2 vb. olarak çağrılır. Bizim durumumuzda sadece bir sinyal modülü mevcut. Bu nedenle, ilk dahil edilen fiyat modülü iki numaradır ve kodda numaralandırma sıfır ile başladığı için filtreyi eklemek üzere "signal.AddFilter(filter1);" dizesini aramamız gerekir. Resim, Şek. 18'dedir:
Şek. 18. Dahil edilme talimatına göre koddaki modül adları
5. Bu kısım zorunlu değildir. Yapılan değişikliklerle açılış fiyatı girintileri, Zararı Durdur, Kar Al ve talimat sona erme süresinden sorumlu Expert parametreleri, kullanımlarını kaybetti. Kodu daha kompakt hale getirmek için aşağıdaki dizeleri silebilirsiniz:
input double Signal_PriceLevel =0.0; // Price level to execute a deal input double Signal_StopLevel =50.0; // Stop Loss level (in points) input double Signal_TakeLevel =50.0; // Take Profit level (in points) input int Signal_Expiration =4; // Expiration of pending orders (in bars)
Yukarıdaki dizeleri sildikten sonra karşılaşılan derleme hatası, bizi silinecek bir sonraki dize grubuna götürür:
signal.PriceLevel(Signal_PriceLevel); signal.StopLevel(Signal_StopLevel); signal.TakeLevel(Signal_TakeLevel); signal.Expiration(Signal_Expiration);
İkincisi silindikten sonra derleme başarılı olacaktır.
Düzenlemeye ilişkin yorumlar ve açıklamalar, "TEST_EA_AO_DZZ_IB_OB" Expert'inin ekteki kodunda bulunabilir. Silinebilecek kodun dizeleri, eşlik eden yorumlara sahiptir.
Sonuç
Bu yazıda MQL5 Sihirbazının uygulama alanını önemli ölçüde genişlettik. Artık mevcut fiyattan bağımsız olarak farklı fiyat seviyelerinde talimat, Zararı Durdur ve Kar Al gerektiren otomatik alım satım sistemlerinin geliştirme optimizasyonu için kullanılabilir.
Oluşturulan Expert'ler, gönderilen talimatların parametrelerini hesaplayan bir dizi fiyat modülü içerebilir. Mevcut olanlardan en uygun parametre seti seçilir. Tercihler ayarlarda belirtilmiştir. Birçok farklı giriş noktasının maksimum verimle kullanılmasına olanak sağlar. Bu yaklaşım, Expert'leri seçici kılar. Yön biliniyorsa ancak giriş noktası tanımlanmamışsa Expert bunun görünmesini bekleyecektir.
Fiyat seviyelerinin araştırılmasından sorumlu standart uyumlu modüllerin tanıtılması önemli bir avantajdır ve Expert'lerin gelişimini basitleştirmeyi amaçlamaktadır. Şu anda sadece üç modül olmasına rağmen, gelecekte sayıları şüphesiz artacaktır. Bu makaleyi faydalı bulduysanız lütfen yorumlarda fiyat modüllerinin çalışmasının algoritmalarını önerin. İlginç fikirler kodda uygulanacaktır.
Bu makale ayrıca, Sihirbazda geliştirilen Expert yeteneklerinin daha da genişletilmesi için bir yöntem sunar. Devralma, değişiklikleri başlatmanın en uygun yoludur.
Programlama becerisine sahip olmayan ancak talimatları izleyerek kodu düzenleyebilen kullanıcılar, mevcut modellere dayalı olarak daha gelişmiş Expert'ler oluşturma fırsatına sahip olur.
MetaQuotes Ltd tarafından Rusçadan çevrilmiştir.
Orijinal makale: https://www.mql5.com/ru/articles/987





- Ücretsiz alım-satım 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