English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
Kendi Takip Eden Durdurma (Trailing Stop) Emrinizi Nasıl Oluşturabilirsiniz?

Kendi Takip Eden Durdurma (Trailing Stop) Emrinizi Nasıl Oluşturabilirsiniz?

MetaTrader 5Göstergeler | 9 Aralık 2021, 11:09
933 0
Dmitry Fedoseev
Dmitry Fedoseev

Giriş

Makalenin konusuna girmeden önce i'leri noktalayıp t'leri geçmenin iyi bir fikir olduğunu düşünüyorum. Bir kez daha "pozisyon" ve "emir" terimlerini tanımlıyoruz:

  • Pozisyon - bir alım satım yükümlülüğüdür, yani bir finansal enstrüman için alınan veya satılan sözleşmelerin sayısıdır. Bir enstrüman başına sadece bir pozisyon olabilir.
  • Emir - bir finansal enstrümanı almak veya satmak için aracıya verilen talimattır. Birkaç emir türü vardır: piyasa ve bekleyen emirlerin yanı sıra durdurma emirleri (Zararı Durdur - Stop Loss ve Kâr Al - Take Profit).

Şekil 1. Pozisyonlar ve Emirler.

Şekil 1. Pozisyonlar ve Emirler.

Bu makale, pozisyonlar için takip eden Zararı Durdur (Trailing Stop Loss) seviyesine odaklanmaktadır. Bekleyen emirler için bu işlem mantıklı değildir, çünkü doğrudan emir fiyatına geçebilirsiniz. Bir pozisyona (veya onun bir bölümüne) dönüştüğünde, bu materyal kullanışlı olacaktır.

İşlem pozisyonu sadece pozisyon iletişim kutusundaki "Kapat" düğmesine basılarak kapatılamaz (Şekil 2).

Şekil 2. Pozisyon iletişim kutusundaki "Kapat" düğmesini kullanarak bir pozisyonu kapatma.

Şekil 2. Pozisyon iletişim kutusundaki "Kapat" düğmesini kullanarak bir pozisyonu kapatma. 1 - pozisyon bağlam menüsünü açın, 2 - "Pozisyonu kapat" öğesini seçin 
3 - "Kapat" düğmesine tıklayın.

Ayrıca, fiyat önceden belirlenmiş bir kâr düzeyine (Kâr Al - Take Profit) veya zarar düzeyine (Zararı Durdur - Stop Loss) ulaştığında pozisyon otomatik olarak kapatılabilir. "Kapat" düğmesini kullanarak pozisyon kapatmanın aksine, Zararı Durdur (Stop Loss) ve Kâr Al (Take Profit) ile kapatma, terminalden (yatırımcı veya uzman tarafından) değil, aracı tarafından yapılır. Böylece, bağlantı ve güç kaynağı ne olursa olsun kapanma pozisyonu tam olarak garanti edilir. Bu, yatırımcının çalışmasında Zararı Durdur (Stop Loss) öğesinin kullanımını pratik olarak zorunlu hale getirir.

Yatırımcının yapması gereken tek eylem - aracıya koruyucu durdurma seviyesini ayarlaması için bir emir vermektir. Başka bir deyişle, pozisyona (veya bu seviye seti ile açık pozisyona) Zararı Durdur (Stop Loss) öğesini ayarlamalısınız. Zararı Durdur (Stop Loss) ayarı, terminaldeki "Değiştir" bağlam menüsü komutu kullanılarak yapılır. Pozisyonlar listesinde bir pozisyon seçin, sağ tıklayın ve "Değiştir veya Sil" seçimini yapın. Ardından, pozisyon iletişim kutusunda gerekli Zararı Durdur (Stop Loss) seviyesini girmeniz ve "Değiştir" düğmesine tıklamanız gerekir (Şekil 3).

Şekil 3. Pozisyonun Zararı Durdur (Stop Loss) Seviyesini Ayarlama.

Şekil 3. Pozisyonun Zararı Durdur (Stop Loss) Seviyesini Ayarlama. 1 - pozisyon bağlam menüsünü açın, 2 - "Değiştir veya Sil"e tıklayın, 3 - değeri ayarlayın, 4 - "Değiştir"e tıklayın. 

Zararı Durdur (Stop Loss) pozisyonunun seviyesi açılış seviyesi ile birlikte fiyat grafiğinde gösterilmektedir (Şekil 4).

Şekil 4. Zararı Durdur (Stop Loss) ile Pozisyon. Seviye, sol kenarda sl ile etiketlenmiş kırmızı noktalı çizgi ile işaretlenmiştir.

Şekil 4. Zararı Durdur (Stop Loss) ile pozisyon. Seviye, sol kenarda sl ile etiketlenmiş kırmızı noktalı çizgi ile işaretlenmiştir.

Sadece pozisyon için Zararı Durdurmayı (Stop Loss) kuramazsınız, aynı zamanda değerini periyodik olarak değiştirebilirsiniz. Örneğin, fiyat kârlı yönde değiştiğinde onu yukarı çekebilir, böylece olası zararı azaltabilirsiniz. Koruyucu seviyenin bu şekilde çekilmesi, takip eden durdurma olarak bilinir.

Çok sayıda takip eden durdurma varyantı vardır: belirli bir mesafedeki fiyattan sonra Zararı Durdurmayı (Stop Loss) kolayca çekebilirsiniz. Zararı Durdur (Stop Loss) hareketine hemen başlayamazsınız ancak pozisyon belirli bir kârlılığa ulaştığında hemen başa baş seviyesine taşınır. Bu değişken standarttır ve MetaTrader 5 İstemci Terminalinde yerleşiktir. Standart takip eden durdurma pozisyonunu kullanmak için sağ tıklayın ve "Takip Eden Durdurma" (Trailing Stop) seçimini yapın (Şekil 5).

Şekil 5. Terminalde standart takip eden durdurmanın etkinleştirilmesi.

Şekil 5. Terminalde standart takip eden durdurmanın etkinleştirilmesi. 1 - pozisyon bağlam menüsünü açın, 2 - "Takip Eden Durdurma" (Trailing Stop) seçimini yapın, 3 - değeri seçin (veya değeri ayarlayın).
Değer ayarlama komutu (Özel)
bağlam menüsünün altındadır ve görüntüde gösterilmez.

Doğrudan fiyat takibine ek olarak, takip eden durdurma bazı teknik göstergeler bazında çalışabilir. Örneğin, hareketli ortalamalara dayalı, kısa vadeli fiyat değişikliklerine tepki vermemeye izin veren, Ichimoku göstergesine dayalı veya daha uygun; ve hatta başlangıçta bu amaç için tasarlanmamış olan Parabolik SAR (Durdur ve Ters Çevir) göstergesinde bile. Şekil 6'ya bakın.  

Şekil 6. Parabolik SAR Göstergesi.

Şekil 6. Parabolik SAR Göstergesi. 

MQL4 yöntemsel programlamasında, bir takip eden durdurma genellikle ayrı bir fonksiyon olarak oluşturulmuştur veya diğer fonksiyonlara entegre edilmiştir. Örneğin, MetaTrader 4'te bulunan MACD Örnek uzmanında, takip eden durdurma fonksiyonu, emirlerin piyasa kapanışı fonksiyonuyla entegre edilmiştir:

for(cnt=0;cnt<total;cnt++)
  {
   OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
   if(OrderType()<=OP_SELL &&         // check for opened position 
      OrderSymbol()==Symbol())        // check for symbol
     {
      if(OrderType()==OP_BUY)         // long position is opened
        {
         // should it be closed?
         if(MacdCurrent>0 && MacdCurrent<SignalCurrent && MacdPrevious>SignalPrevious && 
            MacdCurrent>(MACDCloseLevel*Point))
           {
            OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); // close position
            return(0); // exit
           }
         // check for trailing stop
         if(TrailingStop>0) 
           {
             
            if(Bid-OrderOpenPrice()>Point*TrailingStop)
              {
               if(OrderStopLoss()<Bid-Point*TrailingStop)
                 {
                  OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop,OrderTakeProfit(),0,Green);
                  return(0);
                 }
              }
           }
        }
      else // go to short position
        {
         // should it be closed?
         if(MacdCurrent<0 && MacdCurrent>SignalCurrent && 
            MacdPrevious<SignalPrevious && MathAbs(MacdCurrent)>(MACDCloseLevel*Point))
           {
            OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); // close position
            return(0); // exit
           }
         // check for trailing stop
         if(TrailingStop>0) 
           {
             
            if((OrderOpenPrice()-Ask)>(Point*TrailingStop))
              {
               if((OrderStopLoss()>(Ask+Point*TrailingStop)) || (OrderStopLoss()==0))
                 {
                  OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop,OrderTakeProfit(),0,Red);
                  return(0);
                 }
              }
           }
        }
     }
  }

Nesne Yönelimli Dil olarak MQL5, uzmanların tasarımında çok daha fazla olanak sağlar. Daha sonra hemen hemen her uzmana hızlı ve kolay bir şekilde entegre edilebilecek çok yönlü ve çok fonksiyonlu sınıflar oluşturmanıza olanak tanır. Bu makalede böyle bir sınıf geliştireceğiz.


1. Takip Eden Durdurma İçin Temel Sınıfı Oluşturma

Yukarıda belirtildiği gibi, çok sayıda takip eden durdurma vardır ancak hepsinin ortak işlevsel yönleri vardır:

  • Pozisyonun türünü (yönünü) belirleme
  • Pozisyonun mevcut Zararı Durdur (Stop Loss) seviyesinin belirlenmesi
  • Yeni Zararı Durdur (Stop Loss) seviyesinin hesaplanması
  • Mevcut Zararı Durdur (Stop Loss) seviyesini değiştirme ihtiyacının kontrol edilmesi
  • Pozisyonun Zararı Durdur (Stop Loss) seviyesinin değiştirilmesi

Takip eden durdurma türü, yalnızca hesaplanan Zararı Durdur (Stop Loss) seviyesinin değerini belirleyecektir. Böylece, takip eden durdurmanın temel işlevselliği, temel sınıfa dahil edilecektir. Takip eden durdurma türüne bağlı olan işlevsellik için alt sınıflar oluşturulacaktır. Bu alt sınıfların yöntemlerine uygulama, temel sınıfın sanal yöntemleri ile yapılacaktır.

Teknik göstergeleri kullanmayı planladığımızdan, bunların istikrarlı çalışmasını sağlamak için onlara periyodik araç temin edilmesi gerekmektedir. Bu amaçla zamanlayıcıyı kullanacağız. Ayrıca takip eden durdurmayı (sınıfı mekanik ticaret sisteminin bir parçası olarak kullanırken) açmayı/kapatmayı ve grafiksel nesne düğmesini kullanarak açmayı/kapatmayı (sınıfı yardımcı uzmanların bir parçası olarak kullanırken) planlıyoruz. Bu işlevsel gereksinimlere göre, temel sınıf aşağıdaki yöntemler setine sahip olacaktır:

class CTrailingStop
  {
protected:
public:
   void CTrailingStop(){};
   void ~CTrailingStop(){};
   void Init(){};                   // Initialization of class
   bool StartTimer(){};             // Start timer
   void StopTimer(){};              // Stop timer
   void On(){};                     // Turn on trailing stop
   void Off(){};                    // Turn off trailing stop
   bool DoStoploss(){};             // Main method of controlling level of Stop Loss position
   void EventHandle(){};            // Method of processing chart events (pressing button to turn on trailing stop)
   void Deinit(){};                 // Deinitialization
   virtual bool Refresh(){};        // Refresh indicator
   virtual void Setparameters(){};  // Setting parameters and loading indicator
   virtual int Trend(){};           // Trend shown by indicator
   virtual double BuyStoploss(){};  // Stop Loss value for the Buy position
   virtual double SellStoploss(){}; // Stop Loss value for the Sell position
  };

Init() yöntemini çağırırken, kullanılan takip eden durdurma türüne bağlı olmayan genel parametreleri kabul edecektir. Yöntem, takip eden durdurma modunu ayarlayacak ve bazı piyasa parametreleriyle değişkenler hazırlayacaktır.

  • StartTimer() - göstergelere periyodik adresleme ve onları terminal önbelleğinde kalmaya zorunlu tutmak için gereken zamanlayıcıyı başlatmak için kullanılacaktır.
  • Stoptimer() - uzmanın çalışmasını sonlandırırken zamanlayıcıyı durdurmak için kullanılacaktır.
  • On() - takip eden durdurmayı etkinleştirme ve düğmeyi basılı moda ayarlama (düğme kullanılıyorsa).
  • Off() - takip eden durdurmayı devre dışı bırakma ve düğmeyi basılı moda ayarlama (düğme kullanılıyorsa).
  • DoStoploss() - Zararı Durdur (Stop Loss) pozisyonunun seviyesini kontrol etmenin ana yöntemi
  • EventHandle() - grafik olaylarını işlemek, özellikle düğme pozisyonuna bağlı olarak düğmeye basmaya ve takip eden durdurmayı açmak/kapatmaya yanıt vermek için kullanılır.
  • Deinit() - uzman işini bitirdiğinde çalışır, gösterge tanıtıcı değerinin serbest bırakılmasını sağlar.
  • Refresh() - gösterge değerlerinin yenilenmesini sağlar. Bu yöntem, Zararı Durdur (Stop Loss) değerlerinin hesaplanmasından önce göstergenin mevcut değerlerinin belirlenmesi için gereklidir. Ayrıca, bu yöntem bağımsız olarak kullanılır - göstergeleri çalışır durumda tutmak için zamanlayıcı tarafından periyodik olarak çağrılır.
  • SetParameters() - bu yöntemi çağırdığınızda gösterge parametrelerini kabul eder, gösterge belirtilen parametrelerle yüklenir.
  • Trend() - gösterge ile gösterilen trend bulma yöntemi. Gösterge yukarı yönü gösteriyorsa 1 değerini, aşağı yönü gösteriyorsa -1 değerini verir.
  • BuyStoploss() ve SellStoploss() yöntemleri, gösterge tarafından hesaplanan alım ve satım pozisyonları için yeni Zararı Durdur (Stop Loss) değerlerini verir. 

1.1. init() yöntemi

Init() yöntemi, bir sınıf örneği oluşturulduktan sonra çağrılan ilk yöntemdir. Takip eden durdurma türünden bağımsız olarak genel parametreleri kabul eder: sembol, zaman dilimi, takip eden durdurma modu (tik veya çubuklarla), grafiğe gösterge eklemek veya eklememek, düğme oluşturmak veya oluşturmamak. Ardından düğme özelliklerini kabul eder: Düğmenin X koordinatı, düğmenin Y koordinatı, düğme rengi, düğme başlığı rengi.

Daha fazla çalışma için gerekli olan parametreler sınıf değişkenlerinde saklanır. Ayrıca, Init() yöntemi çalıştığında, takip eden durdurma için gerekli olan değişmeyen ana piyasa parametrelerini belirler: virgülden sonraki basamak sayısı ve nokta değeri. Son olarak, takip eden durdurmanın türüne bağlı olarak düğmenin adı ve başlığı oluşturulur. Bir düğme kullanacak şekilde ayarlanmışsa, oluşturulur. 

"Korumalı" bölümde gerekli tüm değişkenleri bildirelim:

protected:
string m_symbol;             // symbol
ENUM_TIMEFRAMES m_timeframe; // timeframe
bool m_eachtick;             // work on each tick
bool m_indicator;            // show indicator on chart
bool m_button;               // show "turn on/turn off" button
int m_button_x;              // x coordinate of button
int m_button_y;              // y coordinate of button
color m_bgcolor;             // button color
color m_txtcolor;            // button caption color
int m_shift;                 // bar shift
bool m_onoff;                // turned on/turned off
int m_handle;                // indicator handle
datetime m_lasttime;         // time of trailing stop last execution
MqlTradeRequest m_request;   // trade request structure
MqlTradeResult m_result;     // structure of trade request result
int m_digits;                // number of digits after comma for price
double m_point;              // value of point
string m_objname;            // button name
string m_typename;           // name of trailing stop type
string m_caption;            // button caption

Şimdi Init() yönteminin kendisini yazalım:

//--- Trailing stop initialization method
void Init(string             symbol,
          ENUM_TIMEFRAMES timeframe,
          bool   eachtick  =   true,
          bool   indicator =  false,
          bool   button    =  false,
          int    button_x  =      5,
          int    button_y  =     15,
          color  bgcolor   = Silver,
          color  txtcolor  =   Blue)
  {
//--- set parameters
   m_symbol    = symbol;    // symbol
   m_timeframe = timeframe; // timeframe
   m_eachtick  = eachtick;  // true - work on each tick, false - false - work once per bar 
//--- set bar, from which indicator value is used
   if(eachtick)
     {
      m_shift=0; // created bar in per tick mode
     }
   else
     {
      m_shift=1; // created bar in per bar mode
     }
   m_indicator = indicator; // true - attach indicator to chart
   m_button    = button;    // true - create button to turn on/turn off trailing stop
   m_button_x  = button_x;  // x coordinate of button
   m_button_y  = button_y;  // y coordinate of button
   m_bgcolor   = bgcolor;   // button color
   m_txtcolor  = txtcolor;  // button caption color 
//--- get unchanged market history 
   m_digits=(int)SymbolInfoInteger(m_symbol,SYMBOL_DIGITS); // number of digits after comma for price
   m_point=SymbolInfoDouble(m_symbol,SYMBOL_POINT);         // value of point 
//--- creating button name and button caption
   m_objname="CTrailingStop_"+m_typename+"_"+symbol;        // button name
   m_caption=symbol+" "+m_typename+" Trailing";             // button caption 
//--- filling the trade request structure
   m_request.symbol=m_symbol;                               // preparing trade request structure, setting symbol
   m_request.action=TRADE_ACTION_SLTP;                      // preparing trade request structure, setting type of trade action
//--- creating button
   if(m_button)
     {
      ObjectCreate(0,m_objname,OBJ_BUTTON,0,0,0);                 // creating
      ObjectSetInteger(0,m_objname,OBJPROP_XDISTANCE,m_button_x); // setting x coordinate
      ObjectSetInteger(0,m_objname,OBJPROP_YDISTANCE,m_button_y); // setting y coordinate
      ObjectSetInteger(0,m_objname,OBJPROP_BGCOLOR,m_bgcolor);    // setting background color
      ObjectSetInteger(0,m_objname,OBJPROP_COLOR,m_txtcolor);     // setting caption color
      ObjectSetInteger(0,m_objname,OBJPROP_XSIZE,120);            // setting width
      ObjectSetInteger(0,m_objname,OBJPROP_YSIZE,15);             // setting height
      ObjectSetInteger(0,m_objname,OBJPROP_FONTSIZE,7);           // setting font size
      ObjectSetString(0,m_objname,OBJPROP_TEXT,m_caption);        // setting button caption 
      ObjectSetInteger(0,m_objname,OBJPROP_STATE,false);          // setting button state, turned off by default
      ObjectSetInteger(0,m_objname,OBJPROP_SELECTABLE,false);     // user can't select and move button, only click it
      ChartRedraw();                                              // chart redraw 
     }
//--- setting state of trailing stop
   m_onoff=false;                                                 // state of trailing stop - turned on/turned off, turned off by default 
  };

Düğme adı ve başlığı oluşturulurken herhangi bir değerle başlatılmamış m_typename değişkeninin kullanıldığını görebilirsiniz. Buna bir değer atamak, alt sınıf yapıcılarında gerçekleştirilecektir. Bu nedenle, farklı takip eden durdurma yöntemleri kullanıldığında, kullanılan takip eden durdurma türüne karşılık gelen farklı bir değere sahip olacaktır. 

1.2. StartTimer() yöntemi

StartTimer() yöntemi, uzmanın ortak zamanlayıcısını başlatır.  

//--- Start timer
bool StartTimer()
  {
   return(EventSetTimer(1));
  };

Zamanlayıcı kullanırken, göstergeye periyodik olarak başvurmak için Refresh() yönteminin çağrısını OnTimer() fonksiyonuna eklemelisiniz.

1.3. StopTimer() yöntemi

StartTimer() yöntemi, bir uzmanın zamanlayıcısını durdurur.  

//--- Stop timer
void StopTimer()
  {
   EventKillTimer();
  };

Uzman işini bitirdiğinde bu yöntem, kullandıysanız zamanlayıcıyı durdurur. Bu yöntem, bir sınıfın Deinit() yöntemi çalıştırılırken çağrılır.  

1.4. On() yöntemi

On() yöntemi, takip eden durdurmayı açar. Açma, m_onoff değişkenine true değeri atanarak yapılır. Düğme, sınıf başlatmada kullanılmak üzere ayarlanmışsa düğmeye basılır. 

//--- Turn on trailing stop
void On()
  {
   m_onoff=true; 
   if(m_button)
     { // if button is used, it is "pressed"
      if(!ObjectGetInteger(0,m_objname,OBJPROP_STATE))
        {
         ObjectSetInteger(0,m_objname,OBJPROP_STATE,true);
        }
     }
  }

1.5. Off() yöntemi

Off() yöntemi, takip eden durdurmayı kapatır. Kapatma, m_onoff değişkenine false değeri atanarak yapılır. Düğme sınıf başlatmada kullanılmak üzere ayarlanmışsa, düğmeye basılır. 

//--- Turn off trailing stop
void Off()
  {
   m_onoff=false;
   if(m_button)
     { // if button is used, it is "depressed"
      if(ObjectGetInteger(0,m_objname,OBJPROP_STATE))
        {
         ObjectSetInteger(0,m_objname,OBJPROP_STATE,false);
        }
     }
  }

1.6. EventHandle() yöntemi

EventHandle() yöntemi, OnChartEvent() fonksiyonundan çağrılacak ve buna göre OnChartEvent() fonksiyonuna geçirilen tüm parametreleri kabul edecektir.

//--- Method of tracking button state - turned on/turned off
void EventHandle(const int id,const long  &lparam,const double &dparam,const string &sparam)
  {
   if(id==CHARTEVENT_OBJECT_CLICK && sparam==m_objname)
     { // there is an event with button
      if(ObjectGetInteger(0,m_objname,OBJPROP_STATE))
        { // check button state
         On(); // turn on
        }
      else
        {
         Off(); // turn off
        }
     }
  }

CHARTEVENT_OBJECT_CLICK olayı gerçekleşirse ve bu olay m_objname adına (olayın meydana geldiği nesne adı, sparam değişkenine iletilir) sahip düğme ile gerçekleşirse düğmenin durumuna bağlı olarak On() veya Off() yöntemi yürütülür.

1.7. Deinit() yöntemi

Uzman işini bitirdiğinde Deinit() yöntemi çağrılmalıdır. Bu yöntem, zamanlayıcıyı durdurur, gösterge tanıtıcı değerini serbest bırakır ve kullanılmışsa düğmeyi siler. 

//--- Method of deinitialization
void Deinit()
  {
   StopTimer();                  // stop timer
   IndicatorRelease(m_handle);   // release indicator handle
   if(m_button)
     {
      ObjectDelete(0,m_objname); // delete button
      ChartRedraw();             // chart redraw
     }
  }

Refresh(), SetParameters(), Trend(), BuyStoploss() ve SellStoploss() sanal yöntemleri daha sonra takip eden durdurma alt sınıfları oluşturacağımız zaman tartışılacaktır. Şimdi temel sınıfın ana yöntemini - DoStoploss() yöntemini ele alalım.

1.8. DoStoploss() yöntemi

DoStoploss() yöntemi, her bir tikte OnTick() fonksiyonundan çağrılması gereken ana çalışma yöntemidir. m_onoff değişkeninin değeri false ise (takip eden durdurma kapalı), yöntem işini hemen bitirir.  

if(!m_onoff)
  {
   return(true);// if trailing stop is turned off
  }

Ayrıca, takip eden durdurma çubuk başına modunda çalışıyorsa, zaman kontrol edilir - oluşturulan çubuğun zamanı ile fonksiyonun son başarılı yürütme zamanı karşılaştırılır. Zaman eşleşirse, yöntem işini bitirir.

datetime tm[1];
// get the time of last bar in per bar mode 
if(!m_eachtick)
  { 
   // if unable to copy time, finish method, repeat on next tick 
   if(CopyTime(m_symbol,m_timeframe,0,1,tm)==-1)
     {
      return(false); 
     }
   // if the bar time is equal to time of method's last execution - finish method
   if(tm[0]==m_lasttime)
     { 
      return(true);
     }
  }

Takip eden durdurma açıksa ve zaman kontrolü geçildiyse yöntemin ana kısmı yürütülür - gösterge değerleri yenilenir (Refresh() yöntemi çağrılır).

if(!Refresh())
  { // get indicator values
   return(false);
  }

Ardından, Trend() yöntemi tarafından döndürülen değere bağlı olarak, alış veya satış pozisyonu için takip eden durdurma yürütülür.

// depending on trend, shown by indicator, do various actions
switch (Trend())
  {
   // Up trend
   case 1: 
      // code of trailing stop for the buy position
      break;
   // Down trend
   case -1: 
      // code of trailing stop for the sell position
      break;
  }

Çalışmasını satın alma pozisyonu örneği üzerinde düşünün.

if(PositionSelect(m_symbol,1000))
  {   //--- select position. if succeeded, then position exists
   if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
     {//--- if position is buy

      //--- get Stop Loss value for the buy position
      sl=BuyStoploss(); 
      //--- find out allowed level of Stop Loss placement for the buy position
      double minimal=SymbolInfoDouble(m_symbol,SYMBOL_BID)-m_point*SymbolInfoInteger(m_symbol,SYMBOL_TRADE_STOPS_LEVEL);
      //--- value normalizing
      sl=NormalizeDouble(sl,m_digits); 
      //--- value normalizing
      minimal=NormalizeDouble(minimal,m_digits); 
      //--- if unable to place Stop Loss on level, obtained from indicator, 
      //    this Stop Loss will be placed on closest possible level
      sl=MathMin(sl,minimal); 
      //--- value of Stop Loss position
      double possl=PositionGetDouble(POSITION_SL); 
      //--- value normalizing
      possl=NormalizeDouble(possl,m_digits); 
      if(sl>possl)
        {//--- if new value of Stop Loss if bigger than current value of Stop Loss, 
         //    an attempt to move Stop Loss on a new level will be made
         //--- filling request structure
         m_request.sl=sl; 
         //--- filling request structure
         m_request.tp=PositionGetDouble(POSITION_TP); 
         //--- request
         OrderSend(m_request,m_result); 
         if(m_result.retcode!=TRADE_RETCODE_DONE)
           {//--- check request result
            //--- log error message
            printf("Unable to move Stop Loss of position %s, error #%I64u",m_symbol,m_result.retcode); 
            //--- unable to move Stop Loss, finishing
            return(false); 
           }
        }
     }
  }

Pozisyon seçilebiliyorsa bunun türü kontrol edilir. Pozisyon türü trende karşılık geliyorsa BuyStoploss() yöntemini kullanarak gerekli Zararı Durdur (Stop Loss) değerini (sl değişkenine) alırız. Ardından, Zararı Durdurmanın (Stop Loss) ayarlanabileceği izin verilen seviyeyi belirleyin. Hesaplanan seviye izin verilenden daha yakınsa sl değişkeninin değerini ayarlayın. Daha sonra Zararı Durdur (Stop Loss) pozisyonunun mevcut değerini (possl değişkenine) alırız ve sl ve possl değişkenlerinin değerlerini karşılaştırırız. Zararı Durdur (Stop Loss) kimliğinin yeni değeri mevcut değerden daha iyiyse - pozisyonu değiştirin.

Değişiklik yapmadan önce MqlTradeRequest yapısının sl ve tp alanlarını doldurun. m_request.sl değişkeni, gerekli Zararı Durdur (Stop Loss) değeriyle, m_request.tp değişkeni mevcut Kâr Al (Take Profit) değeriyle (değiştirmeden bırakın) atanır. Init() yöntemi çalıştırıldığında kalan alanlar doldurulur. Yapı doldurulduktan sonra OrderSend() fonksiyonu çağrılır.

İşi bittiğinde m_result.retcode değişkeninin değeri kontrol edilir. Değer, TRADE_RETCODE_DONE değerine eşit değilse o zaman herhangi bir nedenle OrderSend() fonksiyonu tarafından istenen eylemi gerçekleştiremedi. Aynı zamanda günlük mesajında hata sayısı ve tamamlama yöntemi ile yürütülür. OrderSend() fonksiyonu başarıyla tamamlandıysa, DoStoploss() yönteminin son çalışmasının yapıldığı çubuğun zamanını hatırlayın. Hata durumunda, çubuk modunda bile bir sonraki tikte yöntemi yeniden denemeye çalışılacaktır. Çalışmalarını başarıyla tamamladığı sürece denemeler devam edecektir.

DoStopLoss() yöntemi kodunun tamamı aşağıdadır.

bool DoStoploss()
  {
//--- if trailing stop is turned off
   if(!m_onoff)
     {
      return(true);
     }
   datetime tm[1];
//--- get the time of last bar in per bar mode
   if(!m_eachtick)
     {
      //--- if unable to copy time, finish method, repeat on next tick 
      if(CopyTime(m_symbol,m_timeframe,0,1,tm)==-1)
        {
         return(false);
        }
      //--- if the bar time is equal to time of method's last execution - finish method
      if(tm[0]==m_lasttime)
        {
         return(true);
        }
     }
//--- get indicator values
   if(!Refresh())
     {
      return(false);
     }
   double sl;
//--- depending on trend, shown by indicator, do various actions
   switch(Trend())
     {
      //--- Up trend
      case 1:
         //--- select position. if succeeded, then position exists
         if(PositionSelect(m_symbol))
           {
            //--- if position is buy
            if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
              {
               //--- get Stop Loss value for the buy position
               sl=BuyStoploss();
               //--- find out allowed level of Stop Loss placement for the buy position
               double minimal=SymbolInfoDouble(m_symbol,SYMBOL_BID)-m_point*SymbolInfoInteger(m_symbol,SYMBOL_TRADE_STOPS_LEVEL);
               //--- value normalizing
               sl=NormalizeDouble(sl,m_digits);
               //--- value normalizing
               minimal=NormalizeDouble(minimal,m_digits);
               //--- if unable to place Stop Loss on level, obtained from indicator, 
               //    this Stop Loss will be placed on closest possible level
               sl=MathMin(sl,minimal);
               //--- value of Stop Loss position
               double possl=PositionGetDouble(POSITION_SL);
               //--- value normalizing
               possl=NormalizeDouble(possl,m_digits);
               //--- if new value of Stop Loss if bigger than current value of Stop Loss, 
               //    an attempt to move Stop Loss on a new level will be made
               if(sl>possl)
                 {
                  //--- filling request structure
                  m_request.sl=sl;
                  //--- filling request structure
                  m_request.tp=PositionGetDouble(POSITION_TP);
                  //--- request
                  OrderSend(m_request,m_result);
                  //--- check request result
                  if(m_result.retcode!=TRADE_RETCODE_DONE)
                    {
                     //--- log error message
                     printf("Unable to move Stop Loss of position %s, error #%I64u",m_symbol,m_result.retcode);
                     //--- unable to move Stop Loss, finishing
                     return(false);
                    }
                 }
              }
           }
         break;
         //--- Down trend
      case -1:
         if(PositionSelect(m_symbol))
           {
            if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
              {
               sl=SellStoploss();
               //--- adding spread, since Sell is closing by the Ask price
               sl+=(SymbolInfoDouble(m_symbol,SYMBOL_ASK)-SymbolInfoDouble(m_symbol,SYMBOL_BID));
               double minimal=SymbolInfoDouble(m_symbol,SYMBOL_ASK)+m_point*SymbolInfoInteger(m_symbol,SYMBOL_TRADE_STOPS_LEVEL);
               sl=NormalizeDouble(sl,m_digits);
               minimal=NormalizeDouble(minimal,m_digits);
               sl=MathMax(sl,minimal);
               double possl=PositionGetDouble(POSITION_SL);
               possl=NormalizeDouble(possl,m_digits);
               if(sl<possl || possl==0)
                 {
                  m_request.sl=sl;
                  m_request.tp=PositionGetDouble(POSITION_TP);
                  OrderSend(m_request,m_result);
                  if(m_result.retcode!=TRADE_RETCODE_DONE)
                    {
                     printf("Unable to move Stop Loss of position %s, error #%I64u",m_symbol,m_result.retcode);
                     return(false);
                    }
                 }
              }
           }
         break;
     }
//--- remember the time of method's last execution
   m_lasttime=tm[0];
   return(true);
  }

Alış ve satış pozisyonları için koddaki farklılıkları not edin. Satış pozisyonu için SellStoploss() tarafından döndürülen değer, satış pozisyonu Satış fiyatı tarafından kapatıldığından için spread değeri kadar artar. Buna göre, alış için Zararı Durdur (Stop Loss) minimum seviyesinin geri sayımı Alış fiyatından, satış için ise Satış fiyatından yapılır.

Şimdilik takip eden durdurma temel sınıfının oluşturulmasını bitirdik. Alt sınıfların oluşturulmasıyla devam edelim. 

2. Parabolik SAR Göstergesi için Takip Eden Durdurma Alt Sınıfı

CTrailingStop sınıfının sanal yöntemleri zaten size bir alt sınıfın içeriğini söyler - SetParameters(), Refresh(), Trend(), BuyStoploss(), SellStoploss() yöntemleri ve takip eden durdurmanın adını ayarlamak için sınıf yapıcı. Sınıf CParabolicStop olarak adlandırılacaktır. Bu sınıf, CTrailingStop öğesinin bir alt sınıfı olduğundan, bildiriminde bundan bahsedilecektir.

class CParabolicStop: public CTrailingStop

Bu bildirimle, CParabolicStop sınıfının sanal yöntemlerinin çağrılması, temel sınıfın devralınmış yöntemlerini çalıştıracaktır.  

Tüm alt sınıf yöntemlerini ayrıntılı olarak ele alalım.

2.1. CParabolicStop() yöntemi

Bu yöntem, sınıfın kendisi ile aynı ada sahiptir, bu yönteme yapıcı denir. Sınıf yüklendiğinde diğer sınıf yöntemlerinden önce otomatik olarak yürütülür. CParabolicStop() yönteminde takip eden durdurmanın adı m_typename değişkenine atanır. Bu değişken, düğme adı ve resim yazısı oluşturmak için kullanılır (temel sınıfın Init() yönteminde).

void CParabolicStop()
  {
   m_typename="SAR"; // setting name of trailing stop type
  };

2.2. SetParameters() yöntemi

SetParameters() yöntemini çağırırken gösterge parametrelerini kabul eder ve gösterge bu parametrelerle yüklenir. m_indicator parametresi, temel sınıfın Init() yöntemi olarak ayarlanmışsa gösterge, grafiğe eklenir (ChartIndicatorAdd() fonksiyonu).

// Method of setting parameters and loading the indicator
bool SetParameters(double sarstep=0.02,double sarmaximum=0.2)
  {
   m_handle=iSAR(m_symbol,m_timeframe,sarstep,sarmaximum); // loading indicator
   if(m_handle==-1)
     {
      return(false); // if unable to load indicator, method returns false
     }
   if(m_indicator)
     {
      ChartIndicatorAdd(0,0,m_handle); // attach indicator to chart
     }
    
   return(true);
  }

2.3. Refresh() yöntemi

Refresh() yöntemi yeni fiyatı alır ve gösterge değerlerini yeniler. Sınıfın "korumalı" bölümünde fiyat değeri için pricebuf dizisi ve gösterge değerleri için indbuf dizisi vardır. Her iki dizinin de tek öğe boyutu vardır - yalnızca bir fiyat değeri ve oluşturan veya oluşturulmuş çubuktan bir gösterge değeri olmalıdır (temel sınıf başlatıldığında ayarlanan m_shift parametresine bağlı olarak).

// Method of getting indicator values
bool Refresh()
  {
   if(CopyBuffer(m_handle,0,m_shift,1,indbuf)==-1)
     {
      return(false); // if unable to copy value to array, return false
     }
    
   if(CopyClose(m_symbol,m_timeframe,m_shift,1,pricebuf)==-1)
     {
      return(false); // if unable to copy value to array, return false
     }    
   return(true); 
  }

2.4. Trend() yöntemi

Trend() yöntemi, gösterge çizgisine göre fiyat konumunu kontrol eder. Fiyat çizginin üzerindeyse bu, yükseliş eğilimidir ve yöntem 1 değerini verir. Fiyat gösterge çizgisinin altındaysa bu, düşüş eğilimidir ve yöntem -1 değerini verir. Fiyatın gösterge çizgisine eşit olduğu durum (nadir, ancak mümkün) hariç tutulmaz. Bu durumda 0 değeri verilir.  

// Method of finding trend
int Trend()
  {
   if(pricebuf[0]>indbuf[0])
     { // price is higher than indicator line, up trend
      return(1);
     }
   if(pricebuf[0]<indbuf[0])
     { // price is lower than indicator line, down trend
      return(-1);
     }    
   return(0);
  }

2.5. BuyStoploss() ve SellStoploss() yöntemleri

Parabolik SAR göstergesinin yalnızca bir satırı olduğundan, her iki yöntem de aynıdır. Refresh() yönteminden elde edilen değeri verirler.

// Method of finding out Stop Loss level for buy
virtual double BuyStoploss()
  {
   return(indbuf[0]);
  };
// Method of finding out Stop Loss level for sell
virtual double SellStoploss()
  {
   return(indbuf[0]);
  };

Şimdilik takip eden durdurma hazır. Henüz sadece bir sınıfı var, ancak zaten kullanılabilir. .\MQL5\Include klasörüne Sample_TrailingStop.mqh adı altında ayrı bir içerik dosyası olarak kaydedin (dosya makaleye eklenmiştir). 

3. Uzmana Parabolik için Takip Eden Durdurma Ekleme

Örneğin makalesindeki My_First_EA gibi bazı uzmanlara, takip eden durdurma eklemeye çalışalım.

3.1. My_First_EA uzmanını MetaEditor'da açın ve My_First_EA_SARTrailing olarak kaydedin.

3.2. Takip eden durdurma dosyasını dahil edin. Uzman kodunun üst kısmına (tercihen dış değişkenlerin bildirilmesinden önce) şu satırı ekleyin: 

#include <Sample_TrailingStop.mqh> // include Trailing Stop class

3.3. Dış değişkenlerden sonra, Trailing olarak adlandırılan CParabolicStop sınıfının bir örneğini oluşturun.

CParabolicStop Trailing; // create class instance 

 3.4. OnInit() fonksiyonunda sınıfı başlatın ve parametrelerini ayarlayın. İlk olarak, gösterge parametreleriyle dış değişkenleri bildirin:

input double TrailingSARStep=0.02;
input double TrailingSARMaximum=0.2;

Ardından OnInit() fonksiyonuna kod ekleyin.

Trailing.Init(_Symbol,PERIOD_CURRENT,true,true,false); // Initialize (set basic parameters)
if(!trailing.setparameters(TrailingSARStep,TrailingSARMaximum))
  { // Set parameters of used trailing stop type
   Alert("trailing error");
   return(-1);
  } 
Trailing.StartTimer(); // Start timer
Trailing.On();         // Turn on

3.5. Uzman kodunda OnTimer() fonksiyonunu bulun. OnTimer() fonksiyonu My_First_EA'da kullanılmaz, bu nedenle onu ekleyin ve ona da Refresh() çağrısını ekleyin. 

void OnTimer()
  {
   Trailing.Refresh();
  }

3.6. OnTick() fonksiyonunun en üstüne DoStoploss() yönteminin çağrısını ekleyin.

3.7. Uzmanı derleyin ve test etmeye çalışın. Uzmanın test sonuçları Şekil 7'de (takip eden durdurma olmadan) ve Şekil 8'de (takip eden durdurma ile) gösterilmektedir.

Şekil 7. Takip Eden Durdurma Olmadan Uzmanın Test Sonuçları.

Şekil 7. Takip Eden Durdurma Olmadan Uzmanın Test Sonuçları.   

Şekil 8. Takip Eden Durdurma ile Uzmanın Test Sonuçları.

Şekil 8. Takip Eden Durdurma ile Uzmanın Test Sonuçları. 

Takip eden durdurmanın kullanılmasının etkili olduğu çok açıktır.

My_First_EA_SARTrailing.mq5 dosyası makaleye eklenmiştir.

4. NRTR için Takip Eden Durdurma Alt Sınıfı

NRTR göstergesi (Nick Rypock Trailing Reverse) adı ve görünümüyle (Şekil 9) üzerinde bir takip eden durdurma oluşturmaya çalışmak için ilgi uyandırır.

Şekil 9. NRTR Göstergesi.

Şekil 9. NRTR Göstergesi.

Gösterge, temel çizgiyi (destek veya direnç çizgisi) ve hedef çizgiyi çizer. Fiyat hedef çizgiyi aştığında, temel çizgi fiyat hareketi yönünde aktarılır, küçük fiyat dalgalanmaları göz ardı edilir. Fiyat taban çizgisiyle kesiştiğinde bu bir trend değişikliği olarak kabul edilir, bu nedenle taban çizgisinin ve hedef çizginin fiyata göre konumunu değiştirir. Yükselen trenddeki destek çizgisi ve hedef çizgisi mavi, aşağı trenddeki kırmızı ile boyanır.

Şimdi NRTR göstergesi için başka bir takip eden durdurma oluşturun.

CNRTRStop temel sınıfına dahil olan başka bir CNRTRStop sınıfı bildirin. 

class CNRTRStop: public CTrailingStop

NRTR alt sınıfı için Takip Eden Durdurma, yapıcı dışında Parabolik için Takip Eden Durdurma ile tamamen aynı yöntemlere sahip olacaktır; şimdi CNRTRStop() olarak adlandırılacaktır.  

4.1. CNRTRStop() yöntemi

Şimdi sınıf yapıcısında m_typename değişkeni, kullanılan göstergeye göre NRTR değeriyle atanır.

void CNRTRStop()
  {
   m_typename="NRTR"; // setting name of trailing stop type
  };

4.2. SetParameters() yöntemi

SetParameters() yöntemini çağırırken, gösterge parametrelerini kabul eder ve yüklenir. Ardından, takip eden durdurmanın temel parametrelerine bağlı olarak, grafiğe gösterge eklenecektir.

// Method of setting parameters and loading the indicator
bool SetParameters(int period,double k)
  {
   m_handle=iCustom(m_symbol,m_timeframe,"NRTR",period,k); // loading indicator
   if(m_handle==-1)
     { // if unable to load indicator, method returns false
      return(false); 
     }
   if(m_indicator)
     {
       
      ChartIndicatorAdd(0,0,m_handle); // attach indicator to chart
     }
   return(true);
  }

4.3. Refresh() yöntemi

Refresh() yöntemi, NRTR göstergesinin iki tamponunu kopyalar - destek hattı tamponu ve direnç çizgisi tamponu.  

 // Method of getting indicator values
bool Refresh()
  {
   if(CopyBuffer(m_handle,0,m_shift,1,sup)==-1)
     {
      return(false); // if unable to copy value to array, return false
     }
    
   if(CopyBuffer(m_handle,1,m_shift,1,res)==-1)
     {
      return(false); // if unable to copy value to array, return false
     }
    
   return(true);
  }

Sınıfın "korumalı" bölümünde iki bildirilmiş dizi vardır: double sup[] ve double res[].

protected:
double sup[1]; // value of support level
double res[1]; // value of resistance level

4.4. Trend() yöntemi

Trend() yöntemi, şu anda hangi satırların var olduğunu kontrol eder. Destek çizgisi varsa bu, göstergenin yükseliş trendini gösterdiği anlamına gelir. Yöntemin kendisi 1 değerini verir. Direnç çizgisi varsa yöntem -1 değerini verir. 

// Method of finding trend
int Trend()
  {
   if(sup[0]!=0)
     { // there is support line, then it is up trend
      return(1);
     }
   if(res[0]!=0)
     { // there is resistance line, then it is down trend
      return(-1);
     }
    
   return(0);
  }

4.5. BuyStoploss() yöntemi

BuyStoploss() yöntemi, destek çizgisinin değerini döndürür. 

// Method of finding out Stop Loss level for buy
double BuyStoploss()
  {
   return(sup[0]);
  }

4.6. SellStoploss() yöntemi

SellStoploss() yöntemi, direnç çizgisinin değerini verir.  

// Method of finding out Stop Loss level for sell
double SellStoploss()
  {
   return(res[0]);
  }

Şimdi takip eden durdurma sınıfı tamamlandı. 

5. Uzmana NRTR için Takip Eden Durdurma Ekleme

Parabolik için takip eden durdurmada olduğu gibi, NRTR için My_First_EA takip eden durdurmayı uzmana ekleyelim.

5.1. MetaEditor'da My_First_EA_SARTrailing uzmanını açın ve My_First_EA_NRTRTrailing olarak kaydedin.

5.2. Parabolik için takip eden durdurmanın dış parametrelerini NRTR için takip eden durdurma parametreleriyle değiştirin.

input int TrailingNRTRPeriod = 40;
input double TrailingNRTRK   =  2;

5.3. CParabolicStop sınıfının bir örneğini oluşturmak yerine, CNRTRStop sınıfının bir örneğini oluşturun. Kod, dış değişkenlerden sonra bulunur. 

CNRTRStop Trailing; // create class instance 

5.4. OnInit() fonksiyonunda, SetParameters() yöntem çağrısının parametrelerini NRTR parametreleriyle değiştirin.

Trailing.SetParameters(TrailingNRTRPeriod,TrailingNRTRK)

5.5. Uzmanı derleyin ve test etmeye çalışın. 

Şekil 10. NRTR için Takip Eden Durdurma ile Uzmanın Test Sonuçları.

Şekil 10. NRTR için Takip Eden Durdurma ile Uzmanın Test Sonuçları.

Takip eden durdurma stratejisine sahip Uzman Danışmanın (Şekil 10) çalışma sonuçları, o stratejiye sahip olmayan bir uzmanın çalışmasına kıyasla (Şekil 7) neredeyse değişmeden kalır. Parabolik için takip eden durdurmanın kullanılması bu uzman için daha etkili oldu. Uzmanlar geliştirirken deneyler yapmak ve en uygun takip eden durdurma türünü seçmek için belirli sayıdaki takip eden durdurma deposunun çok yararlı olabileceği sonucuna varılabilir.  

My_First_EA_NRTRTrailing.mq5 dosyası makaleye eklenmiştir.

6. Uzman-Asistan

Temel bir takip eden durdurma sınıfı oluşturulduğunda, düğme aracılığıyla takip eden durdurmanın açılmasını/kapanmasını kontrol etmek amacıyla düşünülmüştür. Farklı takip eden durdurma türleri ile çeşitli semboller üzerindeki pozisyonları takip etmek için bir uzman-asistan oluşturalım. Uzman pozisyon açmaz, sadece açık pozisyonları takip eder.

6.1. MetaEditor'da Sample_TrailingStop adında yeni bir uzman oluşturun.

6.2. Sample_TrailingStop.mqh dosyasını ekleyin. 

#include <Sample_TrailingStop.mqh> // include Trailing Stop class

6.3. Göstergeler için dış parametreleri bildirin.

input double SARStep=0.02;     // Step of Parabolic
input double SARMaximum=0.02;  // Maximum of Parabolic
input int NRTRPeriod=40;       // NRTR period
input double NRTRK=2;          // NRTR factor

6.4. Uzmanın üzerinde çalışabileceği bir sembol dizisi bildirin.

string Symbols[]={"EURUSD","GBPUSD","USDCHF","USDJPY"};

6.5. Sınıfları yüklemek için dizileri bildirin.

CParabolicStop *SARTrailing[];
CNRTRStop *NRTRTrailing[];

6.6. OnInit() fonksiyonunda, Semboller dizisinin boyutuna göre sınıfları yüklemek için dizileri yeniden boyutlandırın. 

ArrayResize(SARTrailing,ArraySize(Symbols));  // resize according to number of used symbols
ArrayResize(NRTRTrailing,ArraySize(Symbols)); // resize according to number of used symbols 

6.7. Dizinin her elemanı için döngüde sınıf örneğini ekleyin.

for(int i=0;i<ArraySize(Symbols);i++)
  { // for all symbols
   SARTrailing[i]=new CParabolicStop(); // create CParabolicStop class instance
   SARTrailing[i].Init(Symbols[i],PERIOD_CURRENT,false,true,true,5,15+i*17,Silver,Blue);    // initialization of CParabolicStop class instance 
   if(!SARTrailing[i].SetParameters(SARStep,SARMaximum))
     { // setting parameters of CParabolicStop class instance 
      Alert("trailing error");
      return(-1);
     }
   SARTrailing[i].StartTimer();         // start timer
//----
   NRTRTrailing[i]=new CNRTRStop();     // create CNRTRStop class instance
   NRTRTrailing[i].Init(Symbols[i],PERIOD_CURRENT,false,true,true,127,15+i*17,Silver,Blue); // initialization of CNRTRStop class instance
   if(!NRTRTrailing[i].SetParameters(NRTRPeriod,NRTRK))
     { // setting parameters of CNRTRcStop class instance 
      Alert("trailing error");
      return(-1);
     }
   NRTRTrailing[i].StartTimer();        // start timer 
  }

Not: Init() yöntemleri çağrılırken düğmelerin koordinatları hesaplanır. Solda Parabolik ve sağda NRTR için takip eden durdurmanın güç düğmeleri olacaktır.  

6.8. OnTick() fonksiyonunda, her bir takip eden durdurma örneği için DoStoploss() yönteminin çağrısını ekleyin.

for(int i=0;i<ArraySize(Symbols);i++)
  {
   SARTrailing[i].DoStoploss();
   NRTRTrailing[i].DoStoploss();
  }

6.9. Grafik olaylarının işlenmesini ekleyin. 

void OnChartEvent(const int         id,
                  const long   &lparam,
                  const double &dparam,
                  const string &sparam 
                  )
  {
   for(int i=0;i<ArraySize(Symbols);i++)
     {
      SARTrailing[i].EventHandle(id,lparam,dparam,sparam);
      NRTRTrailing[i].EventHandle(id,lparam,dparam,sparam);
     }
    
  }

6.10. Deinit() fonksiyonunda tüm sınıf örneklerini sıfırlayın ve silin.

for(int i=0;i<ArraySize(Symbols);i++)
  {
   SARTrailing[i].Deinit(); 
   NRTRTrailing[i].Deinit();
   delete(SARTrailing[i]);  // delete object
   delete(NRTRTrailing[i]); // delete object
  }

Derleyin, uzmanı grafiğe ekleyin. Grafikte göstergeler ve düğmeler görünür (Şekil 11) - Uzman Danışman çalışmaya hazır.  

Şekil 11. Sample_TrailingStop Başlatıldıktan Sonra Grafikteki Düğmeler ve Göstergeler.

Şekil 11. Sample_TrailingStop Başlatıldıktan Sonra Grafikteki Düğmeler ve Göstergeler. 

Açıldığında ilgili pozisyonu takip etmek için düğmeye basmanız yeterlidir.

Sample_TrailingStop.mq5 dosyası makaleye eklenmiştir.

Sonuç

Mekanik bir alım satım sistemi oluştururken CTrailingStop sınıfını kullanma sıralamasını inceleyelim:

1. Sample_TrailingStop.mqh dosyasını ekleyin.

2. Kullanılan takip eden durdurmanın gösterge parametreleriyle dış değişkenleri bildirin.

3. Sınıf örneğini oluşturun.

4. OnInit() fonksiyonundan Init(), SetParameters(), StartTimer() ve On() yöntemlerinin çağrısını ekleyin.

5. OnTimer() fonksiyonundan Refresh() yönteminin çağrısını ekleyin.

6. OnTick() fonksiyonundan DoStopLoss() yönteminin çağrısını ekleyin.

7. OnDeinit() fonksiyonundan Deinit() yönteminin çağrısını ekleyin. 


5 dakikadan kısa süren yedi adımın ardından Uzman Danışmanınız, takip eden durdurma fonksiyonuna sahip olur!

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

MQL5'te Çok Renkli Göstergeler Oluşturma MQL5'te Çok Renkli Göstergeler Oluşturma
Bu makalemizde çok renkli göstergelerin nasıl oluşturulacağını veya var olan göstergelerin çok renkli hale nasıl dönüştürüleceğini ele alacağız. MQL5, bilgilerin uygun biçimde temsil edilmesini sağlar. Artık göstergelere sahip bir düzine grafiğe bakmak ve RSI veya Stokastik seviyelerinin analizlerini yapmak gerekli değildir, sadece göstergelerin değerlerine bağlı olarak mumları farklı renklerle boyamak daha iyidir.
Alım Satım Robotunun Prototipi Alım Satım Robotunun Prototipi
Bu makale, alım satım sistemlerinin algoritmaları ve elemanlarını oluşturma ilkelerini özetlemekte ve sistematikleştirmektedir. Makale, uzman algoritmasının tasarlanmasını ele almaktadır. Örnek olarak, alım satım sistemlerinin hızlı ve kolay bir şekilde geliştirilmesi için kullanılabilen CExpertAdvisor sınıfı düşünülmüştür.
MQL5'te Trend Bulmanın Birkaç Yolu MQL5'te Trend Bulmanın Birkaç Yolu
Herhangi bir yatırımcı, herhangi bir zamanda bir trendi doğru bir şekilde tespit etme fırsatı için çok şey verir. Belki de herkesin aradığı Kutsal Kase budur. Bu makalede bir trendi tespit etmenin birkaç yolunu ele alacağız. Daha net olmak gerekirse MQL5 aracılığıyla bir trendi tespit etmek için birkaç klasik yolun nasıl programlanacağına bakacağız.
MQL5'te 20 Alım Satım Sinyali MQL5'te 20 Alım Satım Sinyali
Bu makale size bir alım satım sisteminin çalışması için gerekli olan alım satım sinyallerini nasıl alacağınızı öğretecektir. 20 alım satım sinyali oluşturma örneği burada, Uzman Danışmanlar geliştirilirken kullanılabilecek ayrı özel fonksiyonlar olarak verilmiştir. Size kolaylık sağlamak için makalede kullanılan tüm fonksiyonlar, gelecekteki bir Uzman Danışmana kolayca bağlanabilen tek bir mqh içerme dosyasında birleştirilmiştir.