English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
MQL5 Sihirbazı: Alım Satım Sinyalleri Modülü Nasıl Oluşturulur

MQL5 Sihirbazı: Alım Satım Sinyalleri Modülü Nasıl Oluşturulur

MetaTrader 5Ticaret sistemleri | 16 Aralık 2021, 14:44
141 0
MetaQuotes
MetaQuotes

Tanıtım

MetaTrader 5 alım satım fikirlerinin hızlı bir şekilde kontrol edilmesi için güçlü bir araç sunar. Bu, MQL5 Sihirbazının alım satım stratejileri üreticisidir. Uzman Danışman kodlarının otomatik olarak oluşturulması için MQL5 Sihirbazının kullanımı “ MQL5 Sihirbazı: Programlamadan Uzman Danışmanlar Oluşturma” makalesinde açıklanmıştır. Kod oluşturma sisteminin açıklığı standart olanlara kendi alım satım sinyalleri sınıflarınızı, para yönetim sistemlerinizi ve takip modüllerinizi eklemenize olanak tanır.

Bu makale MQL5 Sihirbazı ile Uzman Danışmanlar oluştururken kullanılacak alım satım sinyalleri modüllerini yazma ilkelerini açıklar.

MQL5 Sihirbazı ile oluşturulan Uzman Danışman dört temel sınıfa dayanır:

Şekil 1. CExpert temel sınıfının yapısı

Şekil 1. CExpert temel sınıfının yapısı

CExpert sınıfı (veya alt sınıfı) bir alım satım robotunun ana “motorudur”. Bir CExpert örneği her sınıfın bir kopyasını içerir: CExpertSignal, CExpertMoney veCExpertTrailing (veya alt sınıfları):

  1. CExpertSignal alım satım sinyalleri üretiminin temelidir. CExpert'te bulunan CExpertSignal'den türetilen sınıfın bir örneği yerleşik algoritmalara dayalı olarak piyasaya girme olasılığı, giriş seviyeleri ve koruyucu emirlerin verilmesi hakkında bir Uzman Danışmana bilgi sağlar. Alım satım işlemlerinin yürütülmesine ilişkin nihai karar EA tarafından verilir.
  2. CExpertMoney para ve risk yönetim sistemlerinin temelidir. CExpertMoney'den türetilen sınıfın bir örneği pozisyon açma ve bekleyen emirler verme hacimlerini hesaplar. Hacimle ilgili nihai karar EA tarafından verilir.
  3. CExpertTrailing açık pozisyon desteği modülünün temelidir. CExpertTrailing'den türetilen sınıfın bir örneği bir pozisyonun koruyucu emirlerini değiştirme gerekliliği hakkında bir EA'yı bilgilendirir. Emir değişikliğine ilişkin nihai karar EA tarafından verilir.

Ayrıca CExpert sınıfının üyeleri aşağıdaki sınıfların örnekleridir:

  • CExpertTrade (alım satım için)
  • CIndicators (EA'nın çalışmasına dâhil olan göstergeleri ve zaman dizilerini kontrol etmek için).
  • CSymbolInfo (araç hakkında bilgi almak için)
  • CAccountInfo (alım satım hesabının durumu hakkında bilgi almak için)
  • CPositionInfo (pozisyonlar hakkında bilgi almak için)
  • COorderInfo (bekleyen emirler hakkında bilgi almak için)

Sonraki kısımda “uzman” derken CExpert'in bir örneğini veya alt sınıfını kastediyoruz.

CExpert ile ilgili daha fazla ayrıntı ve onunla yapılan çalışmalar ayrı bir makalede anlatılacaktır.


1. Temel Sınıf CExpertSignal

CExpertSignal alım satım sinyalleri üretiminin temelidir. “Dış dünya” ile iletişim için CExpertSignal bir dizi genel sanal yönteme sahiptir:

Başlatma

Tanım

sanal Init

Sınıf örneğinin başlatılması modül verilerinin EA verileriyle senkronizasyonunu sağlar

sanal ValidationSettings

Ayar parametrelerinin doğrulanması

sanal InitIndicators

Alım satım sinyalleri üreticisinin çalışması için gereken tüm göstergelerin ve zaman serilerinin oluşturulması ve başlatılması

Pozisyon açma/ters çevirme/kapanış sinyalleri

 

sanal CheckOpenLong

Uzun pozisyon açma sinyalinin üretilmesi, giriş seviyelerinin tanımlanması ve koruyucu emirlerin verilmesi

sanal CheckOpenShort

Kısa pozisyon açma sinyalinin üretilmesi, giriş seviyelerinin tanımlanması ve koruyucu emirlerin verilmesi

sanal CheckCloseLong

Çıkış seviyesini tanımlayan uzun pozisyon kapatma sinyalinin üretilmesi

sanal CheckCloseShort

Kısa pozisyon kapatma sinyalinin oluşturulması, çıkış seviyesinin tanımlanması

sanal CheckReverseLong

Uzun pozisyon dönüş sinyalinin oluşturulması, ters çevirme seviyelerinin tanımlanması ve koruyucu emirlerin verilmesi

sanal CheckReverseShort

Kısa pozisyon dönüş sinyalinin oluşturulması, ters çevirme seviyelerinin tanımlanması ve koruyucu emirlerin verilmesi

Bekleyen emirleri yönetme

 

sanal CheckTrailingOrderLong

Bekleyen bir Alış emrinin değişiklik sinyalinin oluşturulması, yeni emir fiyatının tanımlanması

sanal CheckTrailingOrderShort

Bekleyen bir Satış emrinin değişiklik sinyalinin oluşturulması, yeni emir fiyatının tanımlanması

Yöntemlerin Tanımı

1.1. Başlatma yöntemleri:

1.1.1 Init

Init() yöntemi uzmana bir sınıf örneği eklendikten hemen sonra otomatik olarak çağrılır. Yöntemi geçersiz kılma gerekli değildir.

virtual bool Init(CSymbolInfo* symbol, ENUM_TIMEFRAMES period, double adjusted_point);

1.1.2 ValidationSettings

ValidationSettings() yöntemi tüm parametreler ayarlandıktan hemen sonra uzmandan çağrılır. Herhangi bir kurulum parametresi varsa yöntemi geçersiz kılmalısınız.

virtual bool ValidationSettings();

Tüm seçenekler geçerliyse (kullanılabilirse) geçersiz kılınan yöntem true değerini döndürmelidir. Parametrelerden en az biri yanlışsa false değerini döndürmelidir (daha fazla çalışma mümkün değildir).

Temel sınıf CExpertSignal'in ayarlanabilir parametresi yoktur, bu nedenle temel sınıf yöntemi herhangi bir kontrol gerçekleştirmeden her zaman true değerini döndürür.

1.1.3 InitIndicators

InitIndicators() yöntemi gerekli tüm göstergelerin ve zaman serilerinin oluşturulmasını ve başlatılmasını yürütür. Tüm parametreler ayarlandıktan ve doğruluğu başarılı bir şekilde onaylandıktan sonra uzmandan çağrılır. Alım satım sinyali üreticisi en az bir gösterge veya zaman serisi kullanıyorsa yöntem geçersiz kılınmalıdır.

virtual bool InitIndicators(CIndicators* indicators);

Göstergeler veya zaman serileri Standart Kütüphanenin uygun sınıfları aracılığıyla kullanılmalıdır. Tüm göstergelerin veya zaman serilerinin işaretçileri bir uzmanın gösterge koleksiyonuna eklenmelidir (parametre olarak geçirilen bir işaretçi).

Göstergeler veya zaman serileri ile yapılan tüm manipülasyonlar başarılı olursa (kullanım için uygunsa) geçersiz kılınan yöntem true değerini döndürmelidir. Göstergeler veya zaman serileri ile en az bir işlem başarısız olursa yöntem false değerini döndürmelidir (daha fazla çalışma mümkün değildir).

Temel sınıf CExpertSignal göstergeleri veya zaman serilerini kullanmaz; bu nedenle temel sınıf yöntemi herhangi bir eylem gerçekleştirmeden her zaman true değerini döndürür.


1.2. Pozisyon açma sinyalini kontrol etme yöntemleri:

1.2.1 CheckOpenLong

CheckOpenLong() yöntemi giriş seviyesini ve koruyucu emir verme seviyelerini tanımlayarak uzun bir pozisyonun açılış sinyalini üretir. Uzun bir pozisyon açmanın gerekli olup olmadığını belirlemek için bir uzman tarafından çağrılır. Uzun bir pozisyon açma sinyalinin üretilmesi bekleniyorsa yöntem geçersiz kılınmalıdır.

virtual bool CheckOpenLong(double& price, double& sl, double& tp, datetime& expiration);

Yöntem uzun pozisyon açılışının durumunu kontrol etme algoritmasını uygulamalıdır. Koşul yerine getirilirse fiyat, sl, tp ve vade bitimi (parametre olarak geçirilen referanslar) değişkenlerine uygun değerler atanmalı ve yöntem true değerini döndürmelidir. Koşul yerine getirilmezse yöntem false değerini döndürmelidir.

Temel sınıf CExpertSignal uzun bir pozisyon açma sinyali oluşturmak için yerleşik bir algoritmaya sahip değildir; bu nedenle temel sınıf yöntemi her zaman false değerini döndürür.

1.2.2 CheckOpenShort

CheckOpenShort() yöntemi giriş seviyesini ve koruyucu emir verme seviyelerini tanımlayarak kısa bir pozisyonun açılış sinyalini üretir. Kısa bir pozisyon açmanın gerekli olup olmadığını belirlemek için bir uzman tarafından çağrılır. Kısa bir pozisyon açma sinyalinin üretilmesi bekleniyorsa yöntem geçersiz kılınmalıdır. 

virtual bool CheckOpenShort(double& price, double& sl, double& tp, datetime& expiration);

Yöntem kısa pozisyon açılışının durumunu kontrol etme algoritmasını uygulamalıdır. Koşul yerine getirilirse fiyat, sl, tp ve vade bitimi (parametre olarak geçirilen referanslar) değişkenlerine uygun değerler atanmalı ve yöntem true değerini döndürmelidir. Koşul yerine getirilmezse yöntem false değerini döndürmelidir.

Temel sınıf CExpertSignal kısa bir pozisyon açma sinyali oluşturmak için yerleşik bir algoritmaya sahip değildir; bu nedenle temel sınıf yöntemi her zaman false değerini döndürür.


1.3. Pozisyon kapatma sinyalini kontrol etme yöntemleri:

1.3.1 CheckCloseLong

CheckCloseLong() yöntemi çıkış seviyesini tanımlayarak uzun bir pozisyonun kapanış sinyalini üretir. Uzun bir pozisyonu kapatmanın gerekli olup olmadığını belirlemek için bir uzman tarafından çağrılır. Uzun bir pozisyonu kapatma sinyalinin üretilmesi bekleniyorsa yöntem geçersiz kılınmalıdır.

virtual bool CheckCloseLong(double& price);

Yöntem uzun pozisyonun kapanış durumunu kontrol etme algoritmasını uygulamalıdır. Koşul yerine getirilirse fiyat (parametre olarak geçirilen referanslar) değişkenine uygun değer atanmalı ve yöntem true değerini döndürmelidir. Koşul yerine getirilmezse yöntem false değerini döndürmelidir.

Temel sınıf CExpertSignal uzun bir pozisyon kapatma sinyali oluşturmak için yerleşik bir algoritmaya sahip değildir; bu nedenle temel sınıf yöntemi her zaman false değerini döndürür.

1.3.2 CheckCloseShort

CheckCloseShort() yöntemi çıkış seviyesini tanımlayarak kısa bir pozisyonun kapanma sinyalini üretir. Kısa bir pozisyonu kapatmanın gerekli olup olmadığını belirlemek için bir uzman tarafından çağrılır. Kısa bir pozisyonu kapatma sinyalinin üretilmesi bekleniyorsa yöntem geçersiz kılınmalıdır.

virtual bool CheckCloseShort(double& price);

Yöntem kısa pozisyon kapanışının durumunu kontrol etme algoritmasını uygulamalıdır. Koşul yerine getirilirse fiyat (parametre olarak geçirilen referanslar) değişkenine uygun değer atanmalı ve yöntem true değerini döndürmelidir. Koşul yerine getirilmezse yöntem false değerini döndürmelidir.

Temel sınıf CExpertSignal kısa bir pozisyonu kapatma sinyali oluşturmak için yerleşik bir algoritmaya sahip değildir; bu nedenle temel sınıf yöntemi her zaman false değerini döndürür.


1.4. Pozisyonu tersine çevirme sinyalini kontrol etme yöntemleri:

1.4.1 CheckReverseLong

CheckReverseLong yöntemi, tersine çevirme seviyesini ve koruyucu emir verme seviyelerini tanımlayarak uzun bir pozisyonu tersine çevirme sinyalini üretir. Uzun bir pozisyonu tersine çevirmenin gerekli olup olmadığını belirlemek için bir uzman tarafından çağrılır. Uzun bir pozisyonu tersine çevirme sinyalinin üretilmesi bekleniyorsa yöntem geçersiz kılınmalıdır.

virtual bool CheckReverseLong(double& price, double& sl, double& tp, datetime& expiration);

Yöntem uzun bir pozisyonu tersine çevirme durumunu kontrol etme algoritmasını uygulamalıdır. Koşul yerine getirilirse fiyat, sl, tp ve vade bitimi (parametre olarak geçirilen referanslar) değişkenlerine uygun değerler atanmalı ve yöntem true değerini döndürmelidir. Koşul yerine getirilmezse yöntem false değerini döndürmelidir.

CExpertSignal temel sınıfında uzun bir pozisyonu tersine çevirme sinyali oluşturmak için aşağıdaki algoritma uygulanır:

  1. Uzun bir pozisyonu kapatma sinyali kontrol edilir.
  2. Kısa bir pozisyonu açma sinyali kontrol edilir.
  3. Her iki sinyal de etkinse (koşullar yerine getirildiyse) ve kapanış ve açılış fiyatları eşleşirse fiyat, sl, tp ve vade bitimi (parametre olarak geçirilen referanslar) değişkenlerine uygun değerler atanır ve yöntem true değerini döndürür.
Koşul yerine getirilmezse yöntem false değerini döndürür.

1.4.2 CheckReverseShort

CheckReverseShort yöntemi tersine çevirme seviyesini ve koruyucu emir verme seviyelerini tanımlayan, kısa bir pozisyonu tersine çevirme sinyali üretir. Kısa bir pozisyonu tersine çevirmenin gerekli olup olmadığını belirlemek için bir uzman tarafından çağrılır. Temel sınıfta uygulanandan farklı olan algoritmaya göre bir uzun bir pozisyonu tersine çevirme sinyalinin üretilmesi bekleniyorsa yöntem geçersiz kılınmalıdır.

virtual bool CheckReverseShort(double& price, double& sl, double& tp, datetime& expiration);

Yöntem kısa bir pozisyonu tersine çevirme durumunu kontrol etme algoritmasını uygulamalıdır. Koşul yerine getirilirse fiyat, sl, tp ve vade bitimi (parametre olarak geçirilen referanslar) değişkenlerine uygun değerler atanmalı ve yöntem true değerini döndürmelidir. Koşul yerine getirilmezse yöntem false değerini döndürmelidir.

CExpertSignal temel sınıfında kısa bir pozisyonu tersine çevirme sinyali oluşturmak için aşağıdaki algoritma uygulanır:

  1. Kısa bir pozisyonu kapatma sinyali kontrol edilir.
  2. Uzun bir pozisyonu açma sinyali kontrol edilir.
  3. Her iki sinyal de etkinse (koşullar yerine getirildiyse) ve kapanış ve açılış fiyatları eşleşirse fiyat, sl, tp ve vade bitimi (parametre olarak geçirilen referanslar) değişkenlerine uygun değerler atanır ve yöntem true değerini döndürür.

Koşul yerine getirilmezse yöntem false değerini döndürür.


1.5. Bekleyen emir değişikliği sinyalini kontrol etme yöntemleri:

1.5.1 CheckTrailingOrderLong

CheckTrailingOrderLong() yöntemi yeni bir emir fiyatı tanımlayarak bekleyen bir Satın Alma emrinin değişiklik sinyalini üretir. Bekleyen bir Satın Alma emrini değiştirmenin gerekli olup olmadığını belirlemek için bir uzman tarafından çağrılır. Bekleyen bir Satın Alma emrinin değişiklik sinyalinin üretilmesi bekleniyorsa yöntem geçersiz kılınmalıdır.

virtual bool CheckTrailingOrderLong(COrderInfo* order, double& price)

Yöntem bekleyen bir Satın Alma emrinin değişiklik durumunu kontrol etme algoritmasını uygulamalıdır. Koşul yerine getirilirse fiyat (parametre olarak geçirilen referanslar) değişkenine uygun değer atanmalı ve yöntem true değerini döndürmelidir. Koşul yerine getirilmezse yöntem false değerini döndürmelidir.

Temel sınıf CExpertSignal bekleyen bir Satın Alma emrinin değişiklik sinyalini oluşturmak için yerleşik bir algoritmaya sahip değildir; bu nedenle temel sınıf yöntemi her zaman false değerini döndürür.

1.5.2 CheckTrailingOrderShort

CheckTrailingOrderShort() yöntemi yeni bir emir fiyatı tanımlayarak bekleyen bir Satış emrinin değişiklik sinyalini üretir. Bekleyen bir Satış emrini değiştirmenin gerekli olup olmadığını belirlemek için bir uzman tarafından çağrılır. Bekleyen bir Satış emrinin değişiklik sinyalinin üretilmesi bekleniyorsa yöntem geçersiz kılınmalıdır.

virtual bool CheckTrailingOrderShort(COrderInfo* order, double& price)

Yöntem bekleyen bir Satış emrinin değişiklik durumunu kontrol etme algoritmasını uygulamalıdır. Koşul yerine getirilirse fiyat (parametre olarak geçirilen referanslar) değişkenine uygun değer atanmalı ve yöntem true değerini döndürmelidir. Koşul yerine getirilmezse yöntem false değerini döndürmelidir.

Temel sınıf CExpertSignal bekleyen bir Satış emrinin değişiklik sinyalini oluşturmak için yerleşik bir algoritmaya sahip değildir; bu nedenle temel sınıf yöntemi her zaman false değerini döndürür.


2. Kendi Alım Satım Sinyalleri Üreticinizi Oluşturun

ArtıkCExpertSignal temel sınıfının yapısını incelediğinize göre kendi alım satım sinyali üreticinizi oluşturmaya başlayabilirsiniz.

Yukarıda bahsedildiği üzere CExpertSignal sınıfı bir dizi genel sanal “usul”dür; uzmanın, alım satım sinyali üreticisinin piyasaya hangi yönde girileceği konusundaki görüşünü bilebileceği yöntemlerdir.

Bu nedenle birincil hedefimiz, CExpertSignal sınıfından türeterek uygun sanal yöntemleri geçersiz kılarak ve gerekli algoritmaları uygulayarak kendi alım satım sinyali üretici sınıfımızı oluşturmaktır.

İkinci problemimiz de (ki bu da önemlidir), MQL5 Sihirbazında sınıfımızı “görünür” hale getirmektir Fakat her şey sırayla.

2.1. Alım satım sinyalleri üreticinin sınıfını oluşturma

Hadi başlayalım.

İlk olarak, (örneğin, aynı MQL5 Sihirbazını kullanarak) mqh uzantılı bir ekleme dosyası oluşturuyoruz.

Dosya menüsünde “Oluştur”u seçin (veya Ctrl+N basın) ve eklenen bir dosyanın oluşturulmasını belirtin:

Şekil 2. MQL5 Sihirbazını kullanarak bir ekleme dosyası oluşturma.

Şekil 2. MQL5 Sihirbazını kullanarak bir ekleme dosyası oluşturma

Dosyanın daha sonra MQL5 Sihirbazı tarafından sinyal üretici olarak “algılanması” için dosya Include\Expert\Signal\ klasöründe oluşturulmalıdır.

Standart Kütüphane'ye gereksiz dosya atmamak için MQL5 Sihirbazında ilgili parametreleri belirterek SampleSignal.mqh dosyasını oluşturduğumuz Include\Expert\Signal\MySignals klasörünü oluşturun:

Şekil 3. Ekleme dosyasının konumunu ayarlama

Şekil 3. Eklenen dosyanın konumunu ayarlama

MQL5 Sihirbazı işleminin bir sonucu olarak aşağıdaki düzeni oluşturmuş oluruz:

//+------------------------------------------------------------------+
//|                                                 SampleSignal.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| defines                                                          |
//+------------------------------------------------------------------+
// #define MacrosHello   "Hello, world!"
// #define MacrosYear    2010
//+------------------------------------------------------------------+
//| DLL imports                                                      |
//+------------------------------------------------------------------+
// #import "user32.dll"
//   int      SendMessageA(int hWnd,int Msg,int wParam,int lParam);
// #import "my_expert.dll"
//   int      ExpertRecalculate(int wParam,int lParam);
// #import
//+------------------------------------------------------------------+
//| EX5 imports                                                      |
//+------------------------------------------------------------------+
// #import "stdlib.ex5"
//   string ErrorDescription(int error_code);
// #import
//+------------------------------------------------------------------+

Aşağıdakiler sadece “manuel” olarak yapılmalıdır. Gereksiz bölümleri kaldırın ve gerekli olanı ekleyin (Standart Kütüphanenin ExpertSignal.mqh dosyasını ve şu anda boş olan bir sınıf tanımını ekleyin).

//+------------------------------------------------------------------+
//|                                                 SampleSignal.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| include files                                                    |
//+------------------------------------------------------------------+
#include <Expert\ExpertSignal.mqh>
//+------------------------------------------------------------------+
//| The CSampleSignal class.                                         |
//| Purpose: Class of trading signal generator.                      |
//|          It is derived from the CExpertSignal class.             |
//+------------------------------------------------------------------+
class CSampleSignal : public CExpertSignal
  {
  };
//+------------------------------------------------------------------+

Şimdi de algoritmaları seçmemiz gerek.

Alım satım sinyali üreticimizin temeli olarak, yaygın olarak kullanılan “fiyatın hareketli ortalamayla kesiştiği” modeli alıyoruz. Ama bir varsayım daha yapıyoruz: “Hareketli ortalamayla kesiştikten sonra fiyat geri hareket eder ve ancak o zaman doğru yöne gider.” Bunu dosyamıza ekleyelim.

Genel olarak, bir şeyler yazarken yorumları gözden kaçırmayın. Bir süre sonra dikkatli bir şekilde yorumlanmış bir kodu okumak çok rahat olacaktır.

//+------------------------------------------------------------------+
//|                                                 SampleSignal.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| include files                                                    |
//+------------------------------------------------------------------+
#include <Expert\ExpertSignal.mqh>
//+------------------------------------------------------------------+
//| Class CSampleSignal.                                             |
//| Purpose: Class of trading signal generator when price            |
//|          crosses moving average,                                 |
//|          entering on the subsequent back movement.               |
//|          It is derived from the CExpertSignal class.             |
//+------------------------------------------------------------------+
class CSampleSignal : public CExpertSignal
  {
  };
//+------------------------------------------------------------------+

Şimdi alım satım sinyallerinin oluşturulmasıyla ilgili kararlar almak için hangi verilerin gerekli olduğunu tanımlayalım. Bizim durumumuzda bu, önceki çubuğun açılış fiyatı ve kapanış fiyatı ile önceki aynı çubuktaki hareketli ortalamanın değeridir.

Bu verilere erişmek için CiOpen CiClose ve CiMA standart kütüphane sınıflarını kullanıyoruz. Göstergeleri ve zaman serilerini daha sonra tartışacağız.

Bu arada üreticimiz için bir ayar listesi tanımlayalım. İlk olarak, hareketli ortalamayı ayarlamamız gerekiyor. Bu parametreler içinde periyot, zaman ekseni boyunca kayma, ortalama alma yöntemi ve ortalama alma nesnesi yer alır. İkinci olarak, bekleyen emirlerle çalışacağımız için giriş seviyesini, koruyucu emirlerin verilme seviyelerini ve bekleyen bir emrin ömrünü ayarlamamız gerekiyor.

Üreticinin tüm ayarları sınıfın korumalı veri üyelerinde saklanacaktır. Ayarlara erişim uygun genel yöntemlerle gerçekleştirilecektir.

Bu değişiklikleri dosyamıza ekleyelim:

//+------------------------------------------------------------------+
//|                                                 SampleSignal.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| include files                                                    |
//+------------------------------------------------------------------+
#include <Expert\ExpertSignal.mqh>
//+------------------------------------------------------------------+
//| The CSampleSignal class.                                         |
//| Purpose: Class of trading signal generator when price            |
//|             crosses moving average,                              |
//|             entering on the subsequent back movement.            |
//|             It is derived from the CExpertSignal class.          |
//+------------------------------------------------------------------+
class CSampleSignal : public CExpertSignal
  {
protected:
   //--- Setup parameters
   int                m_period_ma;       // averaging period of the MA
   int                m_shift_ma;        // shift of the MA along the time axis
   ENUM_MA_METHOD     m_method_ma;       // averaging method of the MA
   ENUM_APPLIED_PRICE m_applied_ma;      // averaging object of the MA
   double             m_limit;           // level to place a pending order relative to the MA
   double             m_stop_loss;       // level to place a stop loss order relative to the open price
   double             m_take_profit;     // level to place a take profit order relative to the open price
   int                m_expiration;      // lifetime of a pending order in bars

public:
   //--- Methods to set the parameters
   void               PeriodMA(int value)                 { m_period_ma=value;   }
   void               ShiftMA(int value)                  { m_shift_ma=value;    }
   void               MethodMA(ENUM_MA_METHOD value)      { m_method_ma=value;   }
   void               AppliedMA(ENUM_APPLIED_PRICE value) { m_applied_ma=value;  }
   void               Limit(double value)                 { m_limit=value;       }
   void               StopLoss(double value)              { m_stop_loss=value;   }
   void               TakeProfit(double value)            { m_take_profit=value; }
   void               Expiration(int value)               { m_expiration=value;  }
  };
//+------------------------------------------------------------------+

Korumalı veri üyeleri kullandığımız için bu verileri varsayılan değerlerle başlatacağımız bir sınıf oluşturucusu eklememiz gerekiyor.

Parametreleri kontrol etmek için temel sınıfın tanımına göre sanal ValidationSettings yöntemini geçersiz kılalım.

Sınıfın tanımı:

class CSampleSignal : public CExpertSignal
  {
protected:
   //--- Setup parameters
   int                m_period_ma;       // averaging period of the MA
   int                m_shift_ma;        // shift of the MA along the time axis
   ENUM_MA_METHOD     m_method_ma;       // averaging method of the MA
   ENUM_APPLIED_PRICE m_applied_ma;      // averaging object of the MA
   double             m_limit;            // level to place a pending order relative to the MA
   double             m_stop_loss;        // level to place a stop loss order relative to the open price
   double             m_take_profit;      // level to place a take profit order relative to the open price
   int                m_expiration;       // lifetime of a pending order in bars

public:
                      CSampleSignal();
   //--- Methods to set the parameters
   void               PeriodMA(int value)                 { m_period_ma=value;   }
   void               ShiftMA(int value)                  { m_shift_ma=value;    }
   void               MethodMA(ENUM_MA_METHOD value)      { m_method_ma=value;   }
   void               AppliedMA(ENUM_APPLIED_PRICE value) { m_applied_ma=value;  }
   void               Limit(double value)                 { m_limit=value;       }
   void               StopLoss(double value)              { m_stop_loss=value;   }
   void               TakeProfit(double value)            { m_take_profit=value; }
   void               Expiration(int value)               { m_expiration=value;  }
   //--- Methods to validate the parameters
   virtual bool       ValidationSettings();
  };

ValidationSettings() yönteminin uygulanması:


//+------------------------------------------------------------------+
//| Validation of the setup parameters.                              |
//| INPUT:  No.                                                      |
//| OUTPUT: true if the settings are correct, otherwise false.       |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::ValidationSettings()
  {
//--- Validation of parameters
   if(m_period_ma<=0)
     {
      printf(__FUNCTION__+": the MA period must be greater than zero");
      return(false);
     }
//--- ok
   return(true);
  }
//+------------------------------------------------------------------+

Artık hazırlık çalışmalarının çoğunu bitirdiğimize göre göstergeler ve zaman serileri hakkında daha fazla konuşabiliriz.

Göstergeler ve zaman serileri karar verme sürecinde ana bilgi kaynağıdır (yazı tura atmayı veya ayın evrelerini kesinlikle kullanabilirsiniz ancak bunlara resmiyet kazandırmak oldukça zordur).

Yukarıda zaten tanımladığımız üzere, karar vermek için şu bilgilere ihtiyacımız vardır: önceki çubuğun açılış fiyatı, önceki çubuğun kapanış fiyatı ve önceki aynı çubuktaki hareketli ortalamanın değeri.

Bu verilere erişmek için Standart Kütüphanenin aşağıdaki sınıflarını kullanacağız:

  • CiOpen: önceki çubuğun açık fiyatına erişmek için
  • CiClose: önceki çubuğun kapanış fiyatına erişmek için
  • CiMA: önceki çubuktaki hareketli ortalamanın değerine erişmek için.

Şunu sorabilirsiniz: “Tek bir sayı elde etmek için neden bir sınıfta “sarılı” olan göstergeyi veya zaman serisini kullanıyorsunuz?

Bunun birazdan ortaya çıkaracağımız gizli bir anlamı vardır.

Bir gösterge veya zaman serisinin verileri nasıl kullanılır?

İlk önce bir gösterge oluşturmamız gerekiyor.

İkinci olarak, gerekli miktarda veriyi bir ara tampona kopyalamamız gerekiyor.

Üçüncüsü, kopyalamanın tamamlanıp tamamlanmadığını kontrol etmemiz gerekiyor.

Ancak bu adımlardan sonra verileri kullanabilirsiniz.

Standart Kütüphane’nin sınıflarını kullanarak bir gösterge oluşturma gerekliliğinden, ara tamponların kullanılabilirliğiyle ve veri yükleme veya bir işleyicinin serbest bırakılmasıyla ilgilenmekten kurtulursunuz. Uygun bir sınıfın nesnesi bunu sizin için yapar. Gerekli tüm göstergeler başlatma aşamasında sinyal üreticimiz tarafından üretilecek ve tüm göstergelere gerekli geçici tampon sağlanacaktır. Ayrıca koleksiyona bir gösterge veya zaman serisi nesnesi eklediğimizde (özel bir sınıfın nesnesi) verilerin ilişki düzeyini önemsemeyi bırakabilirsiniz (veriler uzman tarafından otomatik olarak güncellenecektir).

Bu sınıfların nesnelerini korumalı veri üyelerine yerleştireceğiz. Her nesne için bir başlatma yöntemi ve veri erişim yöntemi oluşturuyoruz.

InitIndicators sanal yöntemini geçersiz kılalım (temel sınıfın tanımına göre).

Sınıfın tanımı:

class CSampleSignal : public CExpertSignal
  {
protected:
   CiMA               m_MA;              // object to access the values om the moving average
   CiOpen             m_open;            // object to access the bar open prices
   CiClose            m_close;           // object to access the bar close prices
   //--- Setup parameters
   int                m_period_ma;       // averaging period of the MA
   int                m_shift_ma;        // shift of the MA along the time axis
   ENUM_MA_METHOD     m_method_ma;       // averaging method of the MA
   ENUM_APPLIED_PRICE m_applied_ma;      // averaging object of the MA
   double             m_limit;            // level to place a pending order relative to the MA
   double             m_stop_loss;        // level to place a stop loss order relative to the open price
   double             m_take_profit;      // level to place a take profit order relative to the open price
   int                m_expiration;      // lifetime of a pending order in bars

public:
                      CSampleSignal();
   //--- Methods to set the parameters
   void               PeriodMA(int value)                 { m_period_ma=value;              }
   void               ShiftMA(int value)                  { m_shift_ma=value;               }
   void               MethodMA(ENUM_MA_METHOD value)      { m_method_ma=value;              }
   void               AppliedMA(ENUM_APPLIED_PRICE value) { m_applied_ma=value;             }
   void               Limit(double value)                 { m_limit=value;                  }
   void               StopLoss(double value)              { m_stop_loss=value;              }
   void               TakeProfit(double value)            { m_take_profit=value;            }
   void               Expiration(int value)               { m_expiration=value;             }
   //--- Method to validate the parameters
   virtual bool       ValidationSettings();
   //--- Method to validate the parameters
   virtual bool       InitIndicators(CIndicators* indicators);

protected:
   //--- Object initialization method
   bool               InitMA(CIndicators* indicators);
   bool               InitOpen(CIndicators* indicators);
   bool               InitClose(CIndicators* indicators);
   //--- Methods to access object data
   double             MA(int index)                       { return(m_MA.Main(index));       }
   double             Open(int index)                     { return(m_open.GetData(index));  }
   double             Close(int index)                    { return(m_close.GetData(index)); }
  };

InitIndicators, InitMA, InitOpen, InitClose yöntemlerinin uygulanması:

//+------------------------------------------------------------------+
//| Initialization of indicators and timeseries.                     |
//| INPUT:  indicators - pointer to the object - collection of       |
//|                      indicators and timeseries.                  |
//| OUTPUT: true in case of success, otherwise false.                |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::InitIndicators(CIndicators* indicators)
  {
//--- Validation of the pointer
   if(indicators==NULL)       return(false);
//--- Initialization of the moving average
   if(!InitMA(indicators))    return(false);
//--- Initialization of the timeseries of open prices
   if(!InitOpen(indicators))  return(false);
//--- Initialization of the timeseries of close prices
   if(!InitClose(indicators)) return(false);
//--- Successful completion
   return(true);
  }
//+------------------------------------------------------------------+
//| Initialization of the moving average                             |
//| INPUT:  indicators - pointer to the object - collection of       |
//|                      indicators and timeseries.                  |
//| OUTPUT: true in case of success, otherwise false.                |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::InitMA(CIndicators* indicators)
  {
//--- Initialization of the MA object
   if(!m_MA.Create(m_symbol.Name(),m_period,m_period_ma,m_shift_ma,m_method_ma,m_applied_ma))
     {
      printf(__FUNCTION__+": object initialization error");
      return(false);
     }
   m_MA.BufferResize(3+m_shift_ma);
//--- Adding an object to the collection
   if(!indicators.Add(GetPointer(m_MA)))
     {
      printf(__FUNCTION__+": object adding error");
      return(false);
     }
//--- Successful completion
   return(true);
  }
//+------------------------------------------------------------------+
//| Initialization of the timeseries of open prices.                 |
//| INPUT:  indicators - pointer to the object - collection of       |
//|                      indicators and timeseries.                  |
//| OUTPUT: true in case of success, otherwise false.                |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::InitOpen(CIndicators* indicators)
  {
//--- Initialization of the timeseries object
   if(!m_open.Create(m_symbol.Name(),m_period))
     {
      printf(__FUNCTION__+": object initialization error");
      return(false);
     }
//--- Adding an object to the collection
   if(!indicators.Add(GetPointer(m_open)))
     {
      printf(__FUNCTION__+": object adding error");
      return(false);
     }
//--- Successful completion
   return(true);
  }
//+------------------------------------------------------------------+
//| Initialization of the timeseries of close prices.                |
//| INPUT:  indicators - pointer to the object - collection of       |
//|                      indicators and timeseries.                  |
//| OUTPUT: true in case of success, otherwise false.                |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::InitClose(CIndicators* indicators)
  {
//--- Initialization of the timeseries object
   if(!m_close.Create(m_symbol.Name(),m_period))
     {
      printf(__FUNCTION__+": object initialization error");
      return(false);
     }
//--- Adding an object to the collection
   if(!indicators.Add(GetPointer(m_close)))
     {
      printf(__FUNCTION__+": object adding error");
      return(false);
     }
//--- Successful completion
   return(true);
  }
//+------------------------------------------------------------------+

Tüm hazırlık çalışmaları tamamlandı. Gördüğünüz gibi sınıfımız önemli ölçüde büyüdü.

Artık alım satım sinyalleri oluşturmaya hazırız.

Şekil 4. Hareketli ortalamayla kesişen fiyatın alım satım sinyalleri

Şekil 4. Hareketli ortalamayla kesişen fiyatın alım satım sinyalleri

Algoritmalarımızı daha ayrıntılı olarak tekrar ele alalım.

1. Satın alma sinyali önceki çubukta aşağıdaki koşullar yerine getirildiğinde görünür:

  • çubuğun açılış fiyatı hareketli ortalamanın değerinden düşükse
  • çubuğun kapanış fiyatı hareketli ortalamanın değerinden büyükse
  • hareketli ortalama artıyorsa.

Bu durumda ayarlar tarafından tanımlanan parametrelerle bekleyen bir Satın Alma emri vermeyi öneriyoruz. Bu amaçla CheckOpenLong sanal yöntemini geçersiz kılıyoruz ve ilgili fonksiyonu ekliyoruz.

2. Satış sinyali önceki çubukta aşağıdaki koşullar yerine getirildiğinde görünür:

  • çubuğun açılış fiyatı hareketli ortalamanın değerinden büyükse
  • çubuğun kapanış fiyatı hareketli ortalamanın değerinden düşükse
  • hareketli ortalama düşüyorsa.

Bu durumda ayarlar tarafından tanımlanan parametrelerle bekleyen bir Satış emri vermeyi öneriyoruz. Bu amaçla CheckOpenShort sanal yöntemini geçersiz kılıyoruz ve ilgili fonksiyonu ekliyoruz.

3. Pozisyonları kapatmak için sinyal üretmeyeceğiz. Pozisyonların Zarar Durdur/Kâr Et ордерам ile kapatılmasını sağlayacağız.

Bu doğrultuda CheckCloseLong ve CheckCloseShort sanal yöntemlerini geçersiz kılmayacağız.

4. Bekleyen bir emrin ayarlar tarafından belirtilen “mesafede” hareketli ortalama boyunca değiştirilmesini önereceğiz.

 Bu amaçlaCheckTrailingOrderLong ve CheckTrailingOrderShort sanal yöntemlerini geçersiz kılıyoruz ve bunlara karşılık gelen fonksiyonları ekliyoruz.

Sınıfın tanımı:

class CSampleSignal : public CExpertSignal
  {
protected:
   CiMA               m_MA;              // object to access the values of the moving average
   CiOpen             m_open;            // object to access the bar open prices
   CiClose            m_close;           // object to access the bar close prices
   //--- Setup parameters
   int                m_period_ma;       // averaging period of the MA
   int                m_shift_ma;        // shift of the MA along the time axis
   ENUM_MA_METHOD     m_method_ma;       // averaging method of the MA
   ENUM_APPLIED_PRICE m_applied_ma;      // averaging object of the MA
   double             m_limit;            // level to place a pending order relative to the MA
   double             m_stop_loss;        // level to place a stop loss order relative to the open price
   double             m_take_profit;      // level to place a take profit order relative to the open price
   int                m_expiration;       // lifetime of a pending order in bars

public:
                      CSampleSignal();
   //--- Methods to set the parameters

   void               PeriodMA(int value)                 { m_period_ma=value;              }
   void               ShiftMA(int value)                  { m_shift_ma=value;               }
   void               MethodMA(ENUM_MA_METHOD value)      { m_method_ma=value;              }
   void               AppliedMA(ENUM_APPLIED_PRICE value) { m_applied_ma=value;             }
   void               Limit(double value)                 { m_limit=value;                  }
   void               StopLoss(double value)              { m_stop_loss=value;              }
   void               TakeProfit(double value)            { m_take_profit=value;            }
   void               Expiration(int value)               { m_expiration=value;             }
   //--- Method to validate the parameters
   virtual bool       ValidationSettings();
   //--- Method to validate the parameters
   virtual bool       InitIndicators(CIndicators* indicators);
   //--- Methods to generate signals to enter the market
   virtual bool      CheckOpenLong(double& price,double& sl,double& tp,datetime& expiration);
   virtual bool      CheckOpenShort(double& price,double& sl,double& tp,datetime& expiration);
   //--- Methods to generate signals of pending order modification
   virtual bool      CheckTrailingOrderLong(COrderInfo* order,double& price);
   virtual bool      CheckTrailingOrderShort(COrderInfo* order,double& price);

protected:
   //--- Object initialization method
   bool               InitMA(CIndicators* indicators);
   bool               InitOpen(CIndicators* indicators);
   bool               InitClose(CIndicators* indicators);
   //--- Methods to access object data
   double             MA(int index)                       { return(m_MA.Main(index));       }
   double             Open(int index)                     { return(m_open.GetData(index));  }
   double             Close(int index)                    { return(m_close.GetData(index)); }
  };

CheckOpenLong, CheckOpenShort, CheckTrailingOrderLong, CheckTrailingOrderShort yöntemlerinin uygulanması:

//+------------------------------------------------------------------+
//| Check whether a Buy condition is fulfilled                       |
//| INPUT:  price      - variable for open price                     |
//|         sl         - variable for stop loss price,               |
//|         tp         - variable for take profit price              |
//|         expiration - variable for expiration time.               |
//| OUTPUT: true if the condition is fulfilled, otherwise false.     |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::CheckOpenLong(double& price,double& sl,double& tp,datetime& expiration)
  {
//--- Preparing the data
   double spread=m_symbol.Ask()-m_symbol.Bid();
   double ma    =MA(1);
   double unit  =PriceLevelUnit();
//--- Checking the condition
   if(Open(1)<ma && Close(1)>ma && ma>MA(2))
     {
      price=m_symbol.NormalizePrice(ma-m_limit*unit+spread);
      sl   =m_symbol.NormalizePrice(price-m_stop_loss*unit);
      tp   =m_symbol.NormalizePrice(price+m_take_profit*unit);
      expiration+=m_expiration*PeriodSeconds(m_period);
      //--- Condition is fulfilled
      return(true);
     }
//--- Condition is not fulfilled
   return(false);
  }
//+------------------------------------------------------------------+
//| Check whether a Sell condition is fulfilled.                     |
//| INPUT:  price      - variable for open price,                    |
//|         sl         - variable for stop loss,                     |
//|         tp         - variable for take profit                    |
//|         expiration - variable for expiration time.               |
//| OUTPUT: true if the condition is fulfilled, otherwise false.     |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::CheckOpenShort(double& price,double& sl,double& tp,datetime& expiration)
  {
//--- Preparing the data
   double ma  =MA(1);
   double unit=PriceLevelUnit();
//--- Checking the condition
   if(Open(1)>ma && Close(1)<ma && ma<MA(2))
     {
      price=m_symbol.NormalizePrice(ma+m_limit*unit);
      sl   =m_symbol.NormalizePrice(price+m_stop_loss*unit);
      tp   =m_symbol.NormalizePrice(price-m_take_profit*unit);
      expiration+=m_expiration*PeriodSeconds(m_period);
      //--- Condition is fulfilled
      return(true);
     }
//--- Condition is not fulfilled
   return(false);
  }
//+------------------------------------------------------------------+
//| Check whether the condition of modification                      |
//|  of a Buy order is fulfilled.                                    |
//| INPUT:  order - pointer at the object-order,                     |
//|         price - a variable for the new open price.               |
//| OUTPUT: true if the condition is fulfilled, otherwise false.     |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::CheckTrailingOrderLong(COrderInfo* order,double& price)
  {
//--- Checking the pointer
   if(order==NULL) return(false);
//--- Preparing the data
   double spread   =m_symbol.Ask()-m_symbol.Bid();
   double ma       =MA(1);
   double unit     =PriceLevelUnit();
   double new_price=m_symbol.NormalizePrice(ma-m_limit*unit+spread);
//--- Checking the condition
   if(order.PriceOpen()==new_price) return(false);
   price=new_price;
//--- Condition is fulfilled
   return(true);
  }
//+------------------------------------------------------------------+
//| Check whether the condition of modification                      |
//| of a Sell order is fulfilled.                                    |
//| INPUT:  order - pointer at the object-order,                     |
//|         price - a variable for the new open price.               |
//| OUTPUT: true if the condition is fulfilled, otherwise false.     |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::CheckTrailingOrderShort(COrderInfo* order,double& price)
  {
//--- Checking the pointer
   if(order==NULL) return(false);
//--- Preparing the data
   double ma  =MA(1);
   double unit=PriceLevelUnit();
   double new_price=m_symbol.NormalizePrice(ma+m_limit*unit);
//--- Checking the condition
   if(order.PriceOpen()==new_price) return(false);
   price=new_price;
//--- Condition is fulfilled
   return(true);
  }
//+------------------------------------------------------------------+

Böylece ilk sorunu çözmüş olduk. Yukarıdaki kod ana görevimizi yerine getiren alım satım sinyalleri üreticisi sınıfının bir kaynak kodudur.


2.2. MQL5 Sihirbazı için oluşturulan alım satım sinyalleri sınıfının bir tanımını yapma

Şimdi ikinci sorunu çözmeye dönelim. Sinyalimiz MQL5 Sihirbazı alım satım stratejileri üreticisi tarafından “tanınmalıdır”.

İlk gerekli koşulu sağladık: dosyayı MQL5 Sihirbazı tarafından “bulunacağı” yere yerleştirdik. Ama bu yeterli değil. MQL5 Sihirbazı dosyayı yalnızca “bulmak”la kalmamalı, aynı zamanda da “tanımalıdır”. Bunu yapmak için orijinal metne MQL5 Sihirbazı için sınıf tanımlayıcısını eklemeliyiz.

Sınıf tanımlayıcısı belirli kurallara göre oluşturulmuş bir yorum grubudur.

Şimdi bu kuralları ele alalım.

1. Yorum grubu aşağıdaki satırlarla başlamalıdır:

// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |

2. Sonraki satır “//| Title=<Text> |” formatında olan bir metin tanımlayıcısıdır (sinyali seçerken MQL5 Sihirbazında göreceğimiz şey) Metin bir satır için çok büyükse ondan sonra bir satır daha (daha fazlasını değil) ekleyebilirsiniz. 

Durumumuz aşağıdaki gibi oldu:

//| Title=Signal on the crossing of a price and the MA               |
//| entering on its back movement                                    |

3. Daha sonra “//| Type=<Type> |” formatında belirtilen sınıf türüne sahip bir satır olacaktır. <Type> alanı Sinyal değerine sahip olmalıdır (sinyallere ek olarak MQL5 Sihirbazı diğer sınıf türlerini bilir).

Şunu yazın:

//| Type=Signal                                                      |

4. “//| Name=<Name> |” formatında olan aşağıdaki satır sinyalin kısa adıdır (uzmanın global değişkenlerinin adlarını oluşturmak için MQL5 Sihirbazı tarafından kullanılır).

Durum aşağıdaki gibi olacaktır:

//| Name=Sample                                                      |

5. Bir sınıfın adı tanımın önemli bir unsurudur. “//| Class=<ClassNamea> |” formatında olan satırda, <ClassName> parametresi sınıfımızın adıyla eşleşmelidir:

//| Class=CSampleSignal                                              |

6. Bu satırı doldurmuyoruz ancak mevcut olması gerekiyor (bu, dil referansı bölümüne giden bir bağlantıdır):

//| Page=                                                            |

7. Bir de sinyal kurulum parametrelerinin tanımları vardır.

Bu bir satır kümesidir (satır sayısı parametre sayısına eşittir).

Her satırın formatı “//| Parameter=<NameOfMethod>,<TypeOfParameter>,<DefaultValue> |” şeklindedir.

İşte parametre grubumuz:

//| Parameter=PeriodMA,int,12                                        |
//| Parameter=ShiftMA,int,0                                          |
//| Parameter=MethodMA,ENUM_MA_METHOD,MODE_EMA                       |
//| Parameter=AppliedMA,ENUM_APPLIED_PRICE,PRICE_CLOSE               |
//| Parameter=Limit,double,0.0                                       |
//| Parameter=StopLoss,double,50.0                                   |
//| Parameter=TakeProfit,double,50.0                                 |
//| Parameter=Expiration,int,10                                      |

8. Yorum grubu aşağıdaki satırlarla bitmelidir:

//+------------------------------------------------------------------+
// wizard description end

Tanımlayıcıyı kaynak koduna ekleyelim.

//+------------------------------------------------------------------+
//|                                                 SampleSignal.mqh |
//|                        Copyright 2010, MetaQuotes Software Corp. |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2010, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
//+------------------------------------------------------------------+
//| include files                                                    |
//+------------------------------------------------------------------+
#include <Expert\ExpertSignal.mqh>
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class                                         |
//| Title=Signal on crossing of the price and the MA                 |
//| entering on the back movement                                    |
//| Type=Signal                                                      |
//| Name=Sample                                                      |
//| Class=CSampleSignal                                              |
//| Page=                                                            |
//| Parameter=PeriodMA,int,12                                        |
//| Parameter=ShiftMA,int,0                                          |
//| Parameter=MethodMA,ENUM_MA_METHOD,MODE_EMA                       |
//| Parameter=AppliedMA,ENUM_APPLIED_PRICE,PRICE_CLOSE               |
//| Parameter=Limit,double,0.0                                       |
//| Parameter=StopLoss,double,50.0                                   |
//| Parameter=TakeProfit,double,50.0                                 |
//| Parameter=Expiration,int,10                                      |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| CSampleSignal class.                                             |
//| Purpose: Class of trading signal generator when price            |
//|             crosses moving average,                              |
//|             entering on the subsequent back movement.            |
//|             It is derived from the CExpertSignal class.          |
//+------------------------------------------------------------------+
class CSampleSignal : public CExpertSignal
  {
protected:
   CiMA               m_MA;               // object to access the values of the moving average
   CiOpen             m_open;             // object to access the bar open prices
   CiClose            m_close;            // object to access the bar close prices
   //--- Setup parameters
   int                m_period_ma;        // averaging period of the MA
   int                m_shift_ma;         // shift of the MA along the time axis
   ENUM_MA_METHOD     m_method_ma;        // averaging method of the MA
   ENUM_APPLIED_PRICE m_applied_ma;       // averaging object of the MA
   double             m_limit;            // level to place a pending order relative to the MA
   double             m_stop_loss;        // level to place a stop loss order relative to the open price
   double             m_take_profit;      // level to place a take profit order relative to the open price
   int                m_expiration;       // lifetime of a pending order in bars

public:
                      CSampleSignal();
   //--- Methods to set the parameters
   void               PeriodMA(int value)                 { m_period_ma=value;              }
   void               ShiftMA(int value)                  { m_shift_ma=value;               }
   void               MethodMA(ENUM_MA_METHOD value)      { m_method_ma=value;              }
   void               AppliedMA(ENUM_APPLIED_PRICE value) { m_applied_ma=value;             }
   void               Limit(double value)                 { m_limit=value;                  }
   void               StopLoss(double value)              { m_stop_loss=value;              }
   void               TakeProfit(double value)            { m_take_profit=value;            }
   void               Expiration(int value)               { m_expiration=value;             }
   //---Method to validate the parameters
   virtual bool       ValidationSettings();
   //--- Method to validate the parameters
   virtual bool       InitIndicators(CIndicators* indicators);
   //--- Methods to generate signals to enter the market
   virtual bool      CheckOpenLong(double& price,double& sl,double& tp,datetime& expiration);
   virtual bool      CheckOpenShort(double& price,double& sl,double& tp,datetime& expiration);
   //--- Methods to generate signals of pending order modification
   virtual bool      CheckTrailingOrderLong(COrderInfo* order,double& price);
   virtual bool      CheckTrailingOrderShort(COrderInfo* order,double& price);

protected:
   //--- Object initialization method
   bool               InitMA(CIndicators* indicators);
   bool               InitOpen(CIndicators* indicators);
   bool               InitClose(CIndicators* indicators);
   //--- Methods to access object data
   double             MA(int index)                       { return(m_MA.Main(index));       }
   double             Open(int index)                     { return(m_open.GetData(index));  }
   double             Close(int index)                    { return(m_close.GetData(index)); }
  };
//+------------------------------------------------------------------+
//| CSampleSignal Constructor.                                       |
//| INPUT:  No.                                                      |
//| OUTPUT: No.                                                      |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
void CSampleSignal::CSampleSignal()
  {
//--- Setting the default values
   m_period_ma  =12;
   m_shift_ma   =0;
   m_method_ma  =MODE_EMA;
   m_applied_ma =PRICE_CLOSE;
   m_limit      =0.0;
   m_stop_loss  =50.0;
   m_take_profit=50.0;
   m_expiration =10;
  }
//+------------------------------------------------------------------+
//| Validation of parameters.                                        |
//| INPUT:  No.                                                      |
//| OUTPUT: true if the settings are correct, otherwise false.       |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::ValidationSettings()
  {
//--- Validation of parameters
   if(m_period_ma<=0)
     {
      printf(__FUNCTION__+": the MA period must be greater than zero");
      return(false);
     }
//--- Successful completion
   return(true);
  }
//+------------------------------------------------------------------+
//| Initialization of indicators and timeseries.                     |
//| INPUT:  indicators - pointer to the object - collection of       |
//|                      indicators and timeseries.                  |
//| OUTPUT: true in case of success, otherwise false.                |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::InitIndicators(CIndicators* indicators)
  {
//--- Validation of the pointer
   if(indicators==NULL)       return(false);
//--- Initialization of the moving average
   if(!InitMA(indicators))    return(false);
//--- Initialization of the timeseries of open prices
   if(!InitOpen(indicators))  return(false);
//--- Initialization of the timeseries of close prices
   if(!InitClose(indicators)) return(false);
//--- Successful completion
   return(true);
  }
//+------------------------------------------------------------------+
//| Initialization of the moving average                             |
//| INPUT:  indicators - pointer to the object - collection of       |
//|                      indicators and timeseries.                  |
//| OUTPUT: true in case of success, otherwise false.                |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::InitMA(CIndicators* indicators)
  {
//--- Initialization of the MA object
   if(!m_MA.Create(m_symbol.Name(),m_period,m_period_ma,m_shift_ma,m_method_ma,m_applied_ma))
     {
      printf(__FUNCTION__+": object initialization error");
      return(false);
     }
   m_MA.BufferResize(3+m_shift_ma);
//--- Adding an object to the collection
   if(!indicators.Add(GetPointer(m_MA)))
     {
      printf(__FUNCTION__+": object adding error");
      return(false);
     }
//--- Successful completion
   return(true);
  }
//+------------------------------------------------------------------+
//| Initialization of the timeseries of open prices.                 |
//| INPUT:  indicators - pointer to the object - collection of       |
//|                      indicators and timeseries.                  |
//| OUTPUT: true in case of success, otherwise false.                |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::InitOpen(CIndicators* indicators)
  {
//--- Initialization of the timeseries object
   if(!m_open.Create(m_symbol.Name(),m_period))
     {
      printf(__FUNCTION__+": object initialization error");
      return(false);
     }
//--- Adding an object to the collection
   if(!indicators.Add(GetPointer(m_open)))
     {
      printf(__FUNCTION__+": object adding error");
      return(false);
     }
//--- Successful completion
   return(true);
  }
//+------------------------------------------------------------------+
//| Initialization of the timeseries of close prices.                |
//| INPUT:  indicators - pointer to the object - collection of       |
//|                      indicators and timeseries.                  |
//| OUTPUT: true in case of success, otherwise false.                |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::InitClose(CIndicators* indicators)
  {
//--- Initialization of the timeseries object
   if(!m_close.Create(m_symbol.Name(),m_period))
     {
      printf(__FUNCTION__+": object initialization error");
      return(false);
     }
//--- Adding an object to the collection
   if(!indicators.Add(GetPointer(m_close)))
     {
      printf(__FUNCTION__+": object adding error");
      return(false);
     }
//--- Successful completion
   return(true);
  }
//+------------------------------------------------------------------+
//| Check whether a Buy condition is fulfilled                       |
//| INPUT:  price      - variable for open price                     |
//|         sl         - variable for stop loss price,               |
//|         tp         - variable for take profit price              |
//|         expiration - variable for expiration time.               |
//| OUTPUT: true if the condition is fulfilled, otherwise false.     |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::CheckOpenLong(double& price,double& sl,double& tp,datetime& expiration)
  {
//--- Preparing the data
   double spread=m_symbol.Ask()-m_symbol.Bid();
   double ma    =MA(1);
   double unit  =PriceLevelUnit();
//--- Checking the condition
   if(Open(1)<ma && Close(1)>ma && ma>MA(2))
     {
      price=m_symbol.NormalizePrice(ma-m_limit*unit+spread);
      sl   =m_symbol.NormalizePrice(price-m_stop_loss*unit);
      tp   =m_symbol.NormalizePrice(price+m_take_profit*unit);
      expiration+=m_expiration*PeriodSeconds(m_period);
      //--- Condition is fulfilled
      return(true);
     }
//--- Condition is not fulfilled
   return(false);
  }
//+------------------------------------------------------------------+
//| Check whether a Sell condition is fulfilled.                     |
//| INPUT:  price      - variable for open price,                    |
//|         sl         - variable for stop loss,                     |
//|         tp         - variable for take profit                    |
//|         expiration - variable for expiration time.               |
//| OUTPUT: true if the condition is fulfilled, otherwise false.     |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::CheckOpenShort(double& price,double& sl,double& tp,datetime& expiration)
  {
//--- Preparing the data
   double ma  =MA(1);
   double unit=PriceLevelUnit();
//--- Checking the condition
   if(Open(1)>ma && Close(1)<ma && ma<MA(2))
     {
      price=m_symbol.NormalizePrice(ma+m_limit*unit);
      sl   =m_symbol.NormalizePrice(price+m_stop_loss*unit);
      tp   =m_symbol.NormalizePrice(price-m_take_profit*unit);
      expiration+=m_expiration*PeriodSeconds(m_period);
      //--- Condition is fulfilled
      return(true);
     }
//--- Condition is not fulfilled
   return(false);
  }
//+------------------------------------------------------------------+
//| Check whether the condition of modification                      |
//|  of a Buy order is fulfilled.                                    |
//| INPUT:  order - pointer at the object-order,                     |
//|         price - a variable for the new open price.               |
//| OUTPUT: true if the condition is fulfilled, otherwise false.     |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::CheckTrailingOrderLong(COrderInfo* order,double& price)
  {
//--- Checking the pointer
   if(order==NULL) return(false);
//--- Preparing the data
   double spread   =m_symbol.Ask()-m_symbol.Bid();
   double ma       =MA(1);
   double unit     =PriceLevelUnit();
   double new_price=m_symbol.NormalizePrice(ma-m_limit*unit+spread);
//--- Checking the condition
   if(order.PriceOpen()==new_price) return(false);
   price=new_price;
//--- Condition is fulfilled
   return(true);
  }
//+------------------------------------------------------------------+
//| Check whether the condition of modification                      |
//| of a Sell order is fulfilled.                                    |
//| INPUT:  order - pointer at the object-order,                     |
//|         price - a variable for the new open price.               |
//| OUTPUT: true if the condition is fulfilled, otherwise false.     |
//| REMARK: No.                                                      |
//+------------------------------------------------------------------+
bool CSampleSignal::CheckTrailingOrderShort(COrderInfo* order,double& price)
  {
//--- Checking the pointer
   if(order==NULL) return(false);
//--- Preparing the data
   double ma  =MA(1);
   double unit=PriceLevelUnit();
   double new_price=m_symbol.NormalizePrice(ma+m_limit*unit);
//--- Checking the condition
   if(order.PriceOpen()==new_price) return(false);
   price=new_price;
//--- Condition is fulfilled
   return(true);
  }
//+------------------------------------------------------------------+

Pekâlâ, hepsi bu. Sinyal artık kullanılabilir.

MQL5 Sihirbazı üretici alım satım stratejilerinin sinyalimizi kullanabilmesi için MetaEditor’u yeniden başlatmalıyız (MQL5 Sihirbazı Include\Expert klasörünü yalnızca açılışta tarar).

MetaEditor'u yeniden başlattıktan sonra, oluşturulan alım satım sinyalleri modülü MQL5 Sihirbazında kullanılabilir:

Şekil 5. MQL5 Sihirbazında oluşturulan alım satım sinyalleri üreticisi

Şekil 5. MQL5 Sihirbazında oluşturulan alım satım sinyalleri üreticisi

Alım satım sinyalleri üreticisi parametrelerinin tanımı bölümünde belirtilen girdi parametreleri artık mevcuttur:

Şekil 6. MQL5 Sihirbazında oluşturulan alım satım sinyalleri üreticisinin girdi parametreleri

Şekil 6. Şekil 6. MQL5 Sihirbazında oluşturulan alım satım sinyalleri üreticisinin girdi parametreleri

Uygulanan alım satım stratejisinin girdi parametrelerinin en iyi değerleri MetaTrader 5 terminalindeki Strateji Test Edici kullanılarak bulunabilir.


Sonuç

MQL5 Sihirbazının alım satım stratejileri üreticisi alım satım fikirlerinin test edilmesini büyük ölçüde basitleştirir. Oluşturulan uzmanın kodu alım satım sinyali sınıflarının, para ve risk yönetimi sınıflarının ve pozisyon destek sınıflarının belirli uygulamalarını oluşturmak için kullanılan Standart Kütüphanenin alım satım stratejileri sınıflarına dayanmaktadır. 

Bu makale fiyatın ve hareketli ortalamanın kesişimine ilişkin sinyallerin uygulanmasıyla kendi alım satım sinyalleri sınıfınızı nasıl yazacağınız ve bunu MQL5 Sihirbazının alım satım stratejileri oluşturucusuna nasıl ekleyeceğinizle birlikte mql5 Sihirbazı için oluşturulan sınıfın tanımının yapısını ve biçimini açıklar.

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

Ekli dosyalar |
samplesignal.mqh (15.49 KB)
MQL5'te Elektronik Tablolar MQL5'te Elektronik Tablolar
Bu makale ilk boyutunda farklı türde veriler içeren bir dinamik iki boyutlu dizi sınıfını açıklar. Verileri bir tablo biçiminde depolamak farklı türlerdeki bağımlı bilgilerle birçok düzenleme, depolama ve çalıştırma problemlerini çözmek için uygundur. Tablolarla çalışma fonksiyonunu uygulayan sınıfın kaynak kodu makaleye eklenmiştir.
Grafiklerin Analizine Ekonometrik Yaklaşım Grafiklerin Analizine Ekonometrik Yaklaşım
Bu makale ekonometrik analiz yöntemlerini, otokorelasyon analizini ve özellikle koşullu varyans analizini açıklamaktadır. Burada açıklanan yaklaşımın faydası nedir? Doğrusal olmayan GARCH modellerinin kullanımı, analiz edilen serilerin matematiksel açıdan resmi olarak temsil edilmesine ve belirli sayıda adım için bir tahmin oluşturulmasına olanak tanır.
MQL5 Sihirbazı: Risk ve Para Yönetimi Modülü Nasıl Oluşturulur MQL5 Sihirbazı: Risk ve Para Yönetimi Modülü Nasıl Oluşturulur
MQL5 Sihirbazının alım satım stratejileri üreticisi, alım satım fikirlerinin test edilmesini büyük ölçüde basitleştirir. Bu makale özel bir risk ve para yönetimi modülünün nasıl geliştirileceğini ve bunun MQL5 Sihirbazında nasıl etkinleştirileceğini açıklar. Örnek olarak, bu makalede alım satım hacminin boyutunun önceki işlemin sonuçlarına göre belirlendiği bir para yönetimi algoritmasını ele aldık. MQL5 Sihirbazı için oluşturulan sınıfın açıklamasının yapısı ve formatı da bu makalede tartışılmaktadır.
Mikro, Orta ve Ana Eğilimlerin Göstergeleri Mikro, Orta ve Ana Eğilimlerin Göstergeleri
Bu makalenin amacı, James Hyerczyk'in “Pattern, Price & Time: Use Gann Theory in Trading Systems” (Model, Fiyat ve Zaman: Alım Satım Sistemlerinde Gann Teorisini Kullanmak) adlı kitabında göstergelere ve Uzman Danışmanlara yönelik verilen bazı fikirler doğrultusunda alım satım otomasyonunun olanaklarını ve analizini araştırmaktır. Kapsamlı bir makale olmamakla birlikte burada sadece Gann teorisinin ilk bölümünü, yani Modeli araştırıyoruz.