
MQL5 Sihirbazı: Risk ve Para Yönetimi Modülü Nasıl Oluşturulur
Giriş
MetaTrader 5 çeşitli alım satım fikirlerinin hızlı bir şekilde kontrol edilmesi için güçlü bir araç sağlar. Bu, hazır alım satım stratejileri temelinde MQL5 Sihirbazı’nı kullanan Uzman Danışmanlar üreticisidir.
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ı
- CExpert sınıfı (veya alt sınıfı) bir Uzman Danışmanın ana “motorudur”. Bir CExpert örneği her sınıfın bir kopyasını içerir: CExpertSignal, CExpertMoney veCExpertTrailing (veya alt sınıfları):
- 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. Uzman Danışman piyasaya girilip girilmeyeceğine karar verir. CExpertSignal sınıfı ve onunla çalışma hakkında daha fazla ayrıntı “MQL5 Sihirbazı: Alım satım sinyalleri modülü nasıl oluşturulur” adlı makalede verilmiştir.
- CExpertMoney sınıfı risk ve para yönetimi mekanizmasının temelidir. CExpert’te bulunan CExpertMoney'den türetilen sınıfın bir örneği yerleşik algoritmalara dayalı olarak pozisyon açmaya ve bekleyen emirler vermeye ilişkin olası hacimler hakkında bir Uzman Danışmana bilgi sağlar. Uzman Danışman hacim hakkında bir karar verir.
- CExpertTrailing sınıfı açık pozisyon desteği mekanizmasının temelidir. CExpert’te bulunan CExpertTrailing’ten türetilmiş sınıfının bir örneği yerleşik algoritmalara dayalı olarak pozisyonun koruyucu emirlerini değiştirme olasılığı hakkında bir EA'ya bilgi sağlar. Uzman Danışman emirlerin değiştirilmesi hakkında bir karar verir. CExpertTrailing sınıfı ve onunla çalışma hakkında daha fazla ayrıntı ayrı bir makalede anlatılacaktır.
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 CExpertMoney
Yukarıda bahsedildiği üzere CExpertMoney sınıfı risk ve para yönetimi mekanizmasının temelidir. “Dış dünya” ile iletişim için CExpertMoney 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 |
“Risk yüzdesi” parametresinin değerinin ayarlanması | |
sanal ValidationSettings | Ayarlanan parametreleri doğrulama |
sanal InitIndicators | Risk ve para yönetimi mekanizmasının çalışması için gereken tüm göstergelerin ve zaman serilerinin oluşturulması ve başlatılması |
Bir pozisyonu açma/döndürme/kapatma gerekliliğini kontrol etme yöntemleri |
|
sanal CheckOpenLong | Uzun pozisyon açma hacminin belirlenmesi |
sanal CheckOpenShort | Kısa pozisyon açma hacminin belirlenmesi |
sanal CheckReverse | Bir pozisyonu tersine çevirme hacmini belirleme |
sanal CheckClose | Bir pozisyonu kapatma gerekliliğinin belirlenmesi |
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 Percent
Uygun parametreyi yapılandırmak için Percent() yöntemi çağrılır. Bunun değeri 0,0 ila 100,0 arasında olabilir. Varsayılan değer 100,0'dır. Yöntemi geçersiz kılma gerekli değildir.
void Percent(double percent);
1.1.3 ValidationSettings
ValidationSettings() yöntemi tüm parametreler ayarlandıktan hemen sonra uzmandan çağrılır. Ek kurulum parametreleri 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). Geçersiz kılınan yöntem sonucun kontrolüyle temel sınıf yöntemini çağırmalıdır.
1.1.4 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. Risk ve para yönetimi mekanizması 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).
1.2. Bir pozisyonun hacmini belirleme yöntemleri
1.2.1 CheckOpenLong
CheckOpenLong() yöntemi uzun bir pozisyon açma hacmini hesaplar. Uzun pozisyon açma hacminin belirlenmesi için bir uzman tarafından çağrılır. Temel sınıfta uygulanandan farklı bir algoritma kullanarak uzun pozisyon açma hacmini hesaplamayı düşünüyorsanız yöntem geçersiz kılınmalıdır.
\virtual double CheckOpenLong(double price, double sl);
Yöntem uzun bir pozisyon açma hacmini hesaplamaya ilişkin algoritmayı uygulamalıdır. Yöntem hesaplanan hacmi döndürmelidir.
1.2.2 CheckOpenShort
CheckOpenShort() yöntemi kısa bir pozisyon açma hacmini hesaplar. Kısa pozisyon açma hacminin belirlenmesi için bir uzman tarafından çağrılır. Temel sınıfta uygulanandan farklı bir algoritma kullanarak kısa pozisyon açma hacmini hesaplamayı düşünüyorsanız yöntem geçersiz kılınmalıdır.
virtual double CheckOpenShort(double price, double sl);
Yöntem kısa bir pozisyon açma hacmini hesaplamaya ilişkin algoritmayı uygulamalıdır. Yöntem hesaplanan hacmi döndürmelidir.
1.2.3 CheckReverse
CheckReverse() yöntemi bir pozisyonu tersine çevirme hacmini hesaplar. Bir pozisyonu tersine çevirmeye ilişkin olarak bir alım satım işleminin hacmini belirlemek için bir uzman tarafından çağrılır. Temel sınıfta uygulanandan farklı bir algoritma kullanarak pozisyonu tersine çevirme hacmini hesaplamayı düşünüyorsanız (örneğin, çift hacimli ters çevirme) yöntem geçersiz kılınmalıdır.
virtual double CheckReverse(CPositionInfo* position, double sl);
Yöntem bir konumu tersine çevirme hacmini hesaplamaya ilişkin algoritmayı uygulamalıdır; bu bilgiler pozisyon işaretçisi tarafından elde edilebilir. Yöntem bir pozisyonu tersine çevirmeye yönelik hesaplanan hacmi döndürmelidir.
1.2.4 CheckClose
CheckClose() yöntemleri bir pozisyonu kapatmanın gerekli olup olmadığını kontrol eder (para yönetimi ve risk yönetimi açısından). Bir pozisyonu kapatmanın gerekli olup olmadığını belirlemek için bir uzman tarafından çağrılır. Temel sınıfta uygulanandan farklı bir algoritma kullanarak bir pozisyonu kapatmayı düşünüyorsanız (örneğin kısmi kapatma) yöntem geçersiz kılınmalıdır.
virtual double CheckClose(CPositionInfo* position);
Yöntem bir konumu kapatma hacmini hesaplamaya ilişkin algoritmayı uygulamalıdır; bu bilgiler pozisyon işaretçisi tarafından elde edilebilir. Yöntem bir pozisyonu kapatmaya yönelik hesaplanan hacmi döndürmelidir.
2. Para ve Risk Yönetimi Mekanizması Oluşturma
Artık CExpertMoney temel sınıfının yapısını incelediğinize göre kendi risk ve para yönetimi mekanizmanızı oluşturmaya başlayabilirsiniz. Bundan sonra risk ve para yönetimi mekanizması “para yöneticisi” olarak anılacaktır.
Yukarıda bahsedildiği üzere CExpertMoneysınıfı, bir dizi genel sanal “usul”dür; uzmanın, para yöneticisinin belirli bir yönde giriş yapılan piyasanın hacmi hakkındaki görüşünü bilebileceği yöntemlerdir.
Bu nedenle birincil hedefimiz, CExpertMoney sınıfından türeterek, uygun sanal yöntemleri geçersiz kılarak ve gerekli algoritmaları uygulayarak kendi para yöneticisi 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 “Create” (Oluştur) seçeneğini 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
Dosyanın daha sonra MQL5 Sihirbazı tarafından bir para yöneticisi 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 SampleMoney.mqh dosyasını oluşturduğumuz Include\Expert\Money\MyMoneys klasörünü oluşturun:
Şekil 3. Eklenen dosyanın konumunu ayarlama
MQL5 Sihirbazı işleminin bir sonucu olarak aşağıdaki düzeni oluşturmuş oluruz:
//+------------------------------------------------------------------+ //| SampleMoney.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 ExpertMoney.mqh dosyasını ve boş bir sınıf tanımını ekleyin).
//+------------------------------------------------------------------+ //| SampleMoney.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\ExpertMoney.mqh> //+------------------------------------------------------------------+ //| Class CSampleMoney. | //| Purpose: Class for risk and money management. | //| It is derived from the CExpertMoney class. | //+------------------------------------------------------------------+ class CSampleMoney : public CExpertMoney { }; //+------------------------------------------------------------------+
Şimdi de algoritmaları seçmemiz gerek.
Para yöneticimizin temelinde aşağıdaki algoritmayı kullanıyoruz: “Normal” koşullarda sabit ve önceden belirlenmiş bir işlem hacminin kullanılması önerilir. Ancak bir önceki pozisyon zararla kapatılmışsa iki kat hacimli bir pozisyon açılması önerilir.
Bunu dosyamıza ekleyelim.
//+------------------------------------------------------------------+ //| SampleMoney.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\ExpertMoney.mqh> //+------------------------------------------------------------------+ //| Class CSampleMoney. | //| Purpose: Class for risk and money management | //| doubling the volume after a loss deal. | //| It is derived from the CExpertMoney class. | //+------------------------------------------------------------------+ class CSampleMoney : public CExpertMoney { }; //+------------------------------------------------------------------+
Para yöneticimiz için bir ayar listesi tanımlayın. Aslında herhangi bir liste olmayacak. Tüm ayarlar “normal” koşullarda bir işlemin hacmini belirleyecek olan tek bir parametreye dâhil edilmiştir.
Parametre sınıfın korumalı bir veri üyesinde saklanacaktır. Parametreye erişim uygun genel yöntemlerle gerçekleştirilecektir. Sınıf oluşturucusunda parametre varsayılan bir değerle başlatılacaktır. Parametreleri kontrol etmek için temel sınıfın açıklamasına göre sanal ValidationSettings yöntemini geçersiz kılalım.
Bu değişiklikleri dosyamıza ekleyelim:
//+------------------------------------------------------------------+ //| SampleMoney.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\ExpertMoney.mqh> //+------------------------------------------------------------------+ //| Class CSampleMoney. | //| Purpose: Class for risk and money management | //| doubling the volume after a loss deal. | //| It is derived from the CExpertMoney class. | //+------------------------------------------------------------------+ class CSampleMoney : public CExpertMoney { protected: //--- setup parameters double m_lots; // deal volume for "normal" conditions public: CSampleMoney(); //--- methods to set the parameters void Lots(double lots) { m_lots=lots; } }; //+------------------------------------------------------------------+ //| Constructor CSampleMoney. | //| INPUT: no. | //| OUTPUT: no. | //| REMARK: no. | //+------------------------------------------------------------------+ void CSampleMoney::CSampleMoney() { //--- setting the default values m_lots=0.1; } //+------------------------------------------------------------------+
Bundan ayrı olarak, ValidationSettings() yönteminin nasıl uygulanacağını ele alalım. Buradaki mesele, temel sınıfın zaten doğrulama gerektiren bir yapılandırma parametresine sahip olmasıdır.
ValidationSettings() yönteminin uygulanması:
//+------------------------------------------------------------------+ //| Validation of the setup parameters. | //| INPUT: no. | //| OUTPUT: true if the settings are correct, otherwise false. | //| REMARK: no. | //+------------------------------------------------------------------+ bool CSampleMoney::ValidationSettings() { //--- Call the base class method if(!CExpertMoney::ValidationSettings()) return(false); //--- Validation of parameters if(m_lots<m_symbol.LotsMin() || m_lots>m_symbol.LotsMax()) { printf(__FUNCTION__+": the deal volume must be in the range %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax()); return(false); } if(MathAbs(m_lots/m_symbol.LotsStep()-MathRound(m_lots/m_symbol.LotsStep()))>1.0E-10) { printf(__FUNCTION__+": the volume of the deal must be multiple of %f",m_symbol.LotsStep()); return(false); } //--- Successful completion return(true); }
Ayarlar hazır, şimdi para yöneticisinin çalışmasına geçelim. Önceki işlemde kayıp olup olmadığını belirleyecek ve gerekirse hacmini tanımlayacak bir yönteme ihtiyacımız var. Bunu sınıf açıklamasında bildirin:
class CSampleMoney : public CExpertMoney { protected: //--- Setup parameters double m_lots; // deal volume for "normal" conditions public: CSampleMoney(); //--- Methods to set parameters void Lots(double lots) { m_lots=lots; } //--- Methods to validate parameters virtual bool ValidationSettings(); protected: double CheckPrevLoss(); };
Yöntemin uygulanması:
//+------------------------------------------------------------------+ //| Defines whether the prev. deal was losing. | //| INPUT: no. | //| OUTPUT: volume of the prev. deal if it's losing, otherwise 0.0 | //| REMARK: no. | //+------------------------------------------------------------------+ double CSampleMoney::CheckPrevLoss() { double lot=0.0; //--- Request the history of deals and orders HistorySelect(0,TimeCurrent()); //--- variables int deals=HistoryDealsTotal(); // Total number of deals in the history CDealInfo deal; //--- Find the previous deal for(int i=deals-1;i>=0;i--) { if(!deal.SelectByIndex(i)) { printf(__FUNCTION__+": Error of deal selection by index"); break; } //--- Check the symbol if(deal.Symbol()!=m_symbol.Name()) continue; //--- Check the profit if(deal.Profit()<0.0) lot=deal.Volume(); break; } //--- Return the volume return(lot); }
Algoritmalarımızı daha ayrıntılı olarak tekrar ele alalım (zaten ayrıntılı olmasına rağmen).
İnce detaylara girmeden, para yöneticimizin önceki işlemde bir kayıp olduğunda işlemin hacmini arttırmayı önereceğini not edelim. Bir önceki işlemde kayıp olmadıysa belirli bir parametre ile tanımlanan sabit hacimli bir pozisyon açmayı önereceğiz.
Bu amaçla CheckOpenLong ve CheckOpenShort sanal yöntemlerini geçersiz kılıyoruz ve bunlara karşılık gelen fonksiyonları ekliyoruz.
Sınıfın tanımı:
//+------------------------------------------------------------------+ //| Class CSampleMoney. | //| Purpose: Class for risk and money management | //| doubling the volume after a loss deal. | //| It is derived from the CExpertMoney class. | //+------------------------------------------------------------------+ class CSampleMoney : public CExpertMoney { protected: //--- Setup parameters double m_lots; // Deal volume for "normal" conditions public: CSampleMoney(); //--- Methods to set the parameters void Lots(double lots) { m_lots=lots; } //--- Methods to validate the parameters virtual bool ValidationSettings(); //--- Methods to define the volume virtual double CheckOpenLong(double price,double sl); virtual double CheckOpenShort(double price,double sl); protected: double CheckPrevLoss(); };
CheckOpenLong ve CheckOpenShort uygulamaları hemen hemen aynıdır. Her iki yöntem de önceden uygulanmış CheckPrevLoss yöntemini çağırarak hacmi arttırmanın gerekliliğini belirler.
Bunun yanı sıra, alım satım hacmini süresiz olarak arttıramayacağımızı hesaba katmamız gerekiyor. Pozisyon hacminde iki sınırlama mevcuttur:
- Sunucu ayarlarında (SYMBOL_VOLUME_MAX) olarak belirtilen sembol için bir işlemin maksimum hacmi.
- Mevduatta bulunan gerekli miktardaki ücretsiz fon miktarı.
CheckOpenLong ve CheckOpenShort yöntemlerinin uygulanması:
//+------------------------------------------------------------------+ //| Defining the volume to open a long position. | //| INPUT: no. | //| OUTPUT: lot-if successful, 0.0 otherwise. | //| REMARK: not. | //+------------------------------------------------------------------+ double CSampleMoney::CheckOpenLong(double price,double sl) { if(m_symbol==NULL) return(0.0); //--- Select the lot size double lot=2*CheckPrevLoss(); if(lot==0.0) lot=m_lots; //--- Check the limits double maxvol=m_symbol.LotsMax(); if(lot>maxvol) lot=maxvol; //--- Check the margin requirements if(price==0.0) price=m_symbol.Ask(); maxvol=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_BUY,price,m_percent); if(lot>maxvol) lot=maxvol; //--- Return the trade volume return(lot); } //+------------------------------------------------------------------+ //| Defining the volume to open a short position. | //| INPUT: no. | //| OUTPUT: lot-if successful, 0.0 otherwise. | //| REMARK: no. | //+------------------------------------------------------------------+ double CSampleMoney::CheckOpenShort(double price,double sl) { if(m_symbol==NULL) return(0.0); //--- Select the lot size double lot=2*CheckPrevLoss(); if(lot==0.0) lot=m_lots; //--- Check the limits double maxvol=m_symbol.LotsMax(); if(lot>maxvol) lot=maxvol; //--- Check the margin requirements if(price==0.0) price=m_symbol.Bid(); maxvol=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_SELL,price,m_percent); if(lot>maxvol) lot=maxvol; //--- Return the trade volume return(lot); }
Böylece ilk sorunu çözmüş olduk. Yukarıdaki kod ana görevimizi yerine getiren para yöneticisi sınıfının bir “kaynak kodudur”.
2.2. MQL5 Sihirbazı için oluşturulan para yöneticisi sınıfının bir tanımını oluşturma
Şimdi ikinci sorunu çözmeye dönelim. Para yöneticimiz MQL5 Sihirbazının 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.
Ş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=Trade with a doubling of lot after a loss |
3. Daha sonra “//| Type=<Type> |” formatında belirtilen sınıf türüne sahip bir satır olacaktır. <Type> alanı Money değerine sahip olmalıdır (para yöneticilerine ek olarak MQL5 Sihirbazı diğer sınıf türlerini bilir).
Şunu yazın:
//| Type=Money |
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=CSampleMoney |
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=Lots,double,0.1 | //| Parameter=Percent,double,100.0 |
8. Yorum grubu aşağıdaki satırlarla bitmelidir:
//+------------------------------------------------------------------+ // wizard description end
2-7 2. ve 7. maddelere ilişkin daha fazla açıklama yapmamız gerekiyor. Sınıf tanımlayıcısının bölümleri anahtar sözcükleri içerir (Başlık, Tür, Ad, Sınıf, Sayfa, Parametre). Ne yazık ki, MQL5 Sihirbazı tüm olası karakter kombinasyonlarını sınıf açıklamasının bir parçası olarak yorumlayamaz.
Bu nedenle, gereksiz hatalardan kaçınmak için şu şekilde yazın:<Description> yalnızca Başlık anahtar sözcüğü için boşluk içerebilir. 1. ve 8. paragraflar “olduğu gibi” kopyalanmalıdır.
Tanımlayıcıyı kaynak koduna ekleyelim.
//+------------------------------------------------------------------+ //| SampleMoney.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\ExpertMoney.mqh> #include <Trade\DealInfo.mqh> // wizard description start //+------------------------------------------------------------------+ //| Description of the class | //| Title=Trading with lot doubling after a loss | //| Type=Money | //| Name=Sample | //| Class=CSampleMoney | //| Page= | //| Parameter=Lots,double,0.1 | //| Parameter=Percent,double,100.0 | //+------------------------------------------------------------------+ // wizard description end //+------------------------------------------------------------------+ //| Class CSampleMoney. | //| Purpose: Class for risk and money management | //| doubling the volume after a loss deal. | //| It is derived from the CExpertMoney class. | //+------------------------------------------------------------------+ class CSampleMoney : public CExpertMoney { protected: //--- Setup parameters double m_lots; // Deal volume for "normal" conditions public: CSampleMoney(); //--- Methods to set the parameters void Lots(double lots) { m_lots=lots; } //--- Methods to validate the parameters virtual bool ValidationSettings(); //--- Methods to define the volume virtual double CheckOpenLong(double price,double sl); virtual double CheckOpenShort(double price,double sl); protected: double CheckPrevLoss(); }; //+------------------------------------------------------------------+ //| Constructor CSampleMoney. | //| INPUT: no. | //| OUTPUT: no. | //| REMARK: no. | //+------------------------------------------------------------------+ void CSampleMoney::CSampleMoney() { //--- Setting default values m_lots=0.1; } //+------------------------------------------------------------------+ //| Validation of the setup parameters. | //| INPUT: no. | //| OUTPUT: true if the settings are correct, otherwise false. | //| REMARK: no. | //+------------------------------------------------------------------+ bool CSampleMoney::ValidationSettings() { //--- Call the base class method if(!CExpertMoney::ValidationSettings()) return(false); //--- Validating the parameters if(m_lots<m_symbol.LotsMin() || m_lots>m_symbol.LotsMax()) { printf(__FUNCTION__+": The deal volume must be in the range %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax()); return(false); } if(MathAbs(m_lots/m_symbol.LotsStep()-MathRound(m_lots/m_symbol.LotsStep()))>1.0E-10) { printf(__FUNCTION__+": The deal volume must be multiple of %f",m_symbol.LotsStep()); return(false); } //--- Successful completion return(true); } //+------------------------------------------------------------------+ //| Defining the volume to open a long position. | //| INPUT: no. | //| OUTPUT: lot-if successful, 0.0 otherwise. | //| REMARK: no. | //+------------------------------------------------------------------+ double CSampleMoney::CheckOpenLong(double price,double sl) { if(m_symbol==NULL) return(0.0); //--- Select the lot size double lot=2*CheckPrevLoss(); if(lot==0.0) lot=m_lots; //--- Check the limits double maxvol=m_symbol.LotsMax(); if(lot>maxvol) lot=maxvol; //--- Check the margin requirements if(price==0.0) price=m_symbol.Ask(); maxvol=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_BUY,price,m_percent); if(lot>maxvol) lot=maxvol; //--- Return the trade volume return(lot); } //+------------------------------------------------------------------+ //|Defining the volume to open a short position. | //| INPUT: no. | //| OUTPUT: lot-if successful, 0.0 otherwise. | //| REMARK: no. | //+------------------------------------------------------------------+ double CSampleMoney::CheckOpenShort(double price,double sl) { if(m_symbol==NULL) return(0.0); //--- Select the lot size double lot=2*CheckPrevLoss(); if(lot==0.0) lot=m_lots; //--- Check the limits double maxvol=m_symbol.LotsMax(); if(lot>maxvol) lot=maxvol; //--- Check the margin requirements if(price==0.0) price=m_symbol.Bid(); maxvol=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_SELL,price,m_percent); if(lot>maxvol) lot=maxvol; //--- Return the trade volume return(lot); } //+------------------------------------------------------------------+ //| Defines whether the prev. deal was losing. | //| INPUT: no. | //| OUTPUT: Volume of the prev. deal if it's losing, otherwise 0.0 | //| REMARK: no. | //+------------------------------------------------------------------+ double CSampleMoney::CheckPrevLoss() { double lot=0.0; //--- Request the history of deals and orders HistorySelect(0,TimeCurrent()); //--- variables int deals=HistoryDealsTotal(); // Total number of deals in the history CDealInfo deal; //--- Find the previous deal for(int i=deals-1;i>=0;i--) { if(!deal.SelectByIndex(i)) { printf(__FUNCTION__+": Error of deal selection by index"); break; } //--- Check the symbol if(deal.Symbol()!=m_symbol.Name()) continue; //---Check the profit if(deal.Profit()<0.0) lot=deal.Volume(); break; } //--- Return the volume return(lot); } //+------------------------------------------------------------------+
Pekâlâ, hepsi bu. Para yöneticisi kullanıma hazır.
MQL5 Sihirbazı alım satım stratejileri oluşturucusunun para yöneticimizi 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 para yöneticisi modülü MQL5 Sihirbazında kullanılabilir:
Şekil 5. MQL5 Sihirbazında oluşturulan para yöneticisi
Para yöneticisi parametrelerinin tanımı bölümünde belirtilen girdi parametreleri artık mevcuttur:
Şekil 6. MQL5 Sihirbazında oluşturulan para yöneticisinin girdi parametreleri
Uygulanan alım satım stratejisinin giriş parametrelerinin en iyi değerleri MetaTrader 5 terminalindekiStrateji Test Edici kullanılarak bulunabilir.
Şekil 7, bu para yönetim sistemine (EURUSD H1, test süresi) göre işlem yapan Uzman Danışmanın test sonuçlarını göstermektedir: 01.01.2010-05.01.2011).
Şekil 7. Kayıptan sonra ikiye katlanan para yönetimi modülü ile stratejinin geçmişine ilişkin test sonuçları
Uzman Danışman oluştururken “MQL5 Sihirbazı: Alım satım sinyalleri modülü nasıl oluşturulur” adlı makalede verilmiştir. Uzman Danışmanın parametreleri: (PeriodMA=12, ShiftMA=0, MethodMA=MODE_EMA, AppliedMA=PRICE_CLOSE, Limit=-70, ZararDurdur=145, KârAl=430, Vade=10, Lot=0,1, Yüzde=100).
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 ö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 tanımının yapısı ve formatı da açıklanmıştır.
MetaQuotes Ltd tarafından Rusçadan çevrilmiştir.
Orijinal makale: https://www.mql5.com/ru/articles/230





- Ü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