English Русский 中文 Español Deutsch 日本語 Português 한국어 Français Italiano
Otomatik Haber Yatırımcısı Oluşturma

Otomatik Haber Yatırımcısı Oluşturma

MetaTrader 5Ticaret | 13 Ocak 2022, 16:40
247 0
laplacianlab
[Silindi]

Giriş

Investopedia'da belirtildiği üzere bir haber yatırımcısı, "yayınlanan haberlere göre alım satım veya yatırım kararı veren bir tüccar veya yatırımcıdır." Aslında, diğerlerinin yanı sıra bir ülkenin GSYİH'si, tüketici güven endeksleri ve ülkelerin istihdam verileri gibi ekonomik raporlar genellikle döviz piyasalarında önemli hareketlere neden olur. Siz hiç ABD Tarım Dışı İstihdam Verileri açıklamasına katıldınız mı? Katıldıysanız, bu raporların dövizlerin yakın geleceğini belirleyebileceğini ve trendlerin tersine çevrilmesi için katalizör görevi görebileceğini zaten biliyorsunuzdur.

Newspapers B&W

Şekil 1. Newspapers B&W. Flickr üzerinde Creative Commons Lisansı kapsamında dağıtılan resim

1. EA'mızı Programlayalım


1.1. Alım Satım Sistemi Fikri

Bu sistemin arkasındaki fikir yukarıda tartıştığımız fikirdir. Bu kulağa harika geliyor, ancak bu kanıtlanmış gerçeği programlama dünyasına nasıl uygulayabiliriz? Temelde iki MQL5 yönüne güveniyoruz. Bir yandan, bir döviz çiftinde verilen haber dizisinin etkisini ölçmek için Momentum göstergesini kullanacağız. Diğer yandan, favori haber takvimimizi dosya sisteminde saklamak için MQL5 dosya fonksiyonları ile çalışacağız. Seçilen dosya biçimi CSV'dir. Bu robotu, elbette Bir diğer MQL5 OOP sınıfı içinde tartışılan kavramsal yaklaşım ile nesne yönelimli paradigma kapsamında programlayacağız. Nesne yönelimli tasarımımız, CSV'yi, EA'nın bu bilgilere dayanarak kararlar verebileceği şekilde bilgisayarın belleğine yükleyecektir.


1.2. Robotun OOP İskeleti

Şu andan itibaren EA'larımızı, sanki canlı varlıklarmış gibi, kavramlar bakış açısından tasarlayacağız. Şimdi OOP insanları olduk, hatırladınız mı? Bu vizyon sayesinde, Uzman Danışmanımızı bir beyin, evrim olarak adlandırabileceğimiz bir şey, bir dizi gösterge ve bir dizi haber gibi birkaç parçadan oluşturabiliriz. Bunların tamamını aşağıda açıklayacağım.

//+---------------------------------------------------------------------+
//|                                               ExpertNewsWatcher.mq5 |
//|                    Copyright © 2013, laplacianlab, Jordi Bassagañas | 
//+---------------------------------------------------------------------+

#property copyright     "Copyright © 2013, laplacianlab. Jordi Bassagañas"
#property link          "https://www.mql5.com/tr/articles"
#property version       "1.00"
#property tester_file   "news_watcher.csv"  

#include <..\Experts\NewsWatcher\CNewsWatcher.mqh>

input ENUM_TIMEFRAMES   Period=PERIOD_M1;
input int               StopLoss=400;
input int               TakeProfit=600;
input double            LotSize=0.01;
input string            CsvFile="news_watcher.csv";
 
MqlTick tick;
CNewsWatcher* NW = new CNewsWatcher(StopLoss,TakeProfit,LotSize,CsvFile);

int OnInit(void)
  {
   NW.Init();
   NW.GetTechIndicators().GetMomentum().SetHandler(Symbol(), Period, 13, PRICE_CLOSE);
   return(0);
  }

void OnDeinit(const int reason)
  {
   delete(NW);
  }

void OnTick()
  {
   SymbolInfoTick(_Symbol, tick);              
   NW.GetTechIndicators().GetMomentum().UpdateBuffer(2);
   NW.OnTick(tick.ask,tick.bid);
  }
//+------------------------------------------------------------------+

CNewsWatcher EA'nın ana sınıfıdır. Koda bir bakalım:

//+---------------------------------------------------------------------+
//|                                                    CNewsWatcher.mqh |
//|                                  Copyright © 2013, Jordi Bassagañas |
//+---------------------------------------------------------------------+
#include <Trade\Trade.mqh>
#include <Mine\Enums.mqh>
#include <..\Experts\NewsWatcher\CBrain.mqh>
#include <..\Experts\NewsWatcher\CEvolution.mqh>
#include <..\Experts\NewsWatcher\CTechIndicators.mqh>
//+---------------------------------------------------------------------+
//| CNewsWatcher Class                                                  |
//+---------------------------------------------------------------------+
class CNewsWatcher
  {
protected:
   //--- Custom types
   CBrain               *m_brain;
   CEvolution           *m_evolution;
   CTechIndicators      *m_techIndicators; 
   //--- MQL5 types
   CTrade               *m_trade;
   CPositionInfo        *m_positionInfo;
public:
   //--- Constructor and destructor methods
                        CNewsWatcher(int stop_loss,int take_profit,double lot_size,string csv_file);
                        ~CNewsWatcher(void);
   //--- Getter methods
   CBrain               *GetBrain(void);
   CEvolution           *GetEvolution(void);
   CTechIndicators      *GetTechIndicators(void);
   CTrade               *GetTrade(void);
   CPositionInfo        *GetPositionInfo(void);
   //--- CNewsWatcher methods
   bool                 Init();
   void                 Deinit(void);
   void                 OnTick(double ask,double bid);
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CNewsWatcher::CNewsWatcher(int stop_loss,int take_profit,double lot_size, string csv_file)
  {
   m_brain=new CBrain(stop_loss,take_profit,lot_size,csv_file);
   m_evolution=new CEvolution(DO_NOTHING);
   m_techIndicators=new CTechIndicators;
   m_trade=new CTrade();
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CNewsWatcher::~CNewsWatcher(void)
  {
   Deinit();
  }
//+------------------------------------------------------------------+
//| GetBrain                                                         |
//+------------------------------------------------------------------+
CBrain *CNewsWatcher::GetBrain(void)
  {
   return m_brain;
  }
//+------------------------------------------------------------------+
//| GetEvolution                                                     |
//+------------------------------------------------------------------+
CEvolution *CNewsWatcher::GetEvolution(void)
  {
   return m_evolution;
  }
//+------------------------------------------------------------------+
//| GetTechIndicators                                                |
//+------------------------------------------------------------------+
CTechIndicators *CNewsWatcher::GetTechIndicators(void)
  {
   return m_techIndicators;
  }  
//+------------------------------------------------------------------+
//| GetTrade                                                         |
//+------------------------------------------------------------------+
CTrade *CNewsWatcher::GetTrade(void)
  {
   return m_trade;
  }
//+------------------------------------------------------------------+
//| GetPositionInfo                                                  |
//+------------------------------------------------------------------+
CPositionInfo *CNewsWatcher::GetPositionInfo(void)
  {
   return m_positionInfo;
  }
//+------------------------------------------------------------------------+
//| CNewsWatcher OnTick                                                    |
//| Checks momentum's turbulences around the time of the news release      |
//+------------------------------------------------------------------------+
void CNewsWatcher::OnTick(double ask,double bid)
  {
//--- are there some news to process?  
   if(GetBrain().GetNewsContainer().GetCurrentIndex() < GetBrain().GetNewsContainer().GetTotal())
   {     
      double momentumBuffer[];
      
      GetTechIndicators().GetMomentum().GetBuffer(momentumBuffer, 2);
      
      //--- Number of seconds before the news releases. GMT +- timeWindow is the real time from which the robot starts 
      //--- listening to the market. For instance, if there is a news release programmed at 13:00 GMT you can set TimeWindow 
      //--- to 900 seconds so that the EA starts listening to the market fifteen minutes before that news release. 
      int timeWindow=600;
      
      CNew *currentNew = GetBrain().GetNewsContainer().GetCurrentNew();      
      int indexCurrentNew = GetBrain().GetNewsContainer().GetCurrentIndex();
            
      if(TimeGMT() >= currentNew.GetTimeRelease() + timeWindow)
      {
         GetBrain().GetNewsContainer().SetCurrentIndex(indexCurrentNew+1);
         return;
      }
      
      //--- is there any open position?
      if(!m_positionInfo.Select(_Symbol))
      {
         //--- if there is no open position, we try to open one
         bool timeHasCome = TimeGMT() >= currentNew.GetTimeRelease() - timeWindow && TimeGMT() <= currentNew.GetTimeRelease() + timeWindow;
             
         if(timeHasCome && momentumBuffer[0] > 100.10)
         {
            GetEvolution().SetStatus(SELL);
            GetBrain().GetNewsContainer().SetCurrentIndex(indexCurrentNew+1);
         }
         else if(timeHasCome && momentumBuffer[0] < 99.90)
         {
            GetEvolution().SetStatus(BUY);
            GetBrain().GetNewsContainer().SetCurrentIndex(indexCurrentNew+1);
         }
      }
      //--- if there is an open position, we let it work the mathematical expectation
      else 
      {
         GetEvolution().SetStatus(DO_NOTHING);         
      }  
      
      double tp;
      double sl; 

      switch(GetEvolution().GetStatus())
      {      
         case BUY:
            tp = ask + m_brain.GetTakeProfit() * _Point;
            sl = bid - m_brain.GetStopLoss() * _Point;
            GetTrade().PositionOpen(_Symbol,ORDER_TYPE_BUY,m_brain.GetSize(),ask,sl,tp);
            break;

         case SELL:
            sl = ask + m_brain.GetStopLoss() * _Point;
            tp = bid - m_brain.GetTakeProfit() * _Point;
            GetTrade().PositionOpen(_Symbol,ORDER_TYPE_SELL,m_brain.GetSize(),bid,sl,tp);
            break;

         case DO_NOTHING:
            // Nothing...
            break;
      }
   }   
//--- we exit when all the container's news have been processed
   else return;
  }
//+------------------------------------------------------------------+
//| CNewsWatcher initialization                                      |
//+------------------------------------------------------------------+
bool CNewsWatcher::Init(void)
  {
// Initialization logic here...
   return true;
  }
//+------------------------------------------------------------------+
//| CNewsWatcher deinitialization                                    |
//+------------------------------------------------------------------+
void CNewsWatcher::Deinit(void)
  {
   delete(m_brain);
   delete(m_evolution);
   delete(m_techIndicators);
   delete(m_trade);
   Print("CNewsWatcher deinitialization performed!");
   Print("Thank you for using this EA.");
  }
//+------------------------------------------------------------------+

Şimdilik, her şeyi çok net anlamadıysanız endişelenmeyin, bu normal. İlk olarak, her şeyin nasıl çalıştığını anlamak için bu Uzman Danışmanın bütün bölümlerini incelemeniz gerekir. İlk olarak bu makaleyi yüzeysel olarak okumanızı, ardından daha derin ikinci ve üçüncü okumalar yapmanızı tavsiye ederim. Bu arada ben de CNewsWatcher'ın bazı kilit kısımlarını açıklamaya çalışacağım.

EA'nın en önemli kısmı, tabi ki, CNewsWatcher'ın çalışma için bir OO haber kapsayıcı kullandığını göreceğiniz OnTick yöntemidir. Gerçek dünyadaki bir gazete olarak görülebilecek bu parça, EA kullanıcısının alım satım yapmak istediği haberleri içerir. 

Haber kapsayıcısını şu şekilde aldığımızı unutmayın:

GetBrain().GetNewsContainer();

Ve işlenecek güncel haberleri şu şekilde alıyoruz:

CNew *currentNew = GetBrain().GetNewsContainer().GetCurrentNew();   

Bu da CBrain aracılığıyla yapılıyor. EA'nın doğru bir şekilde çalışması için gerekli olan şeyleri içeren nesne yönelimli tasarımımızda CBrain'in önemli bir merkezi nokta olduğunu unutmayın, bu salt okunur bellek (ROM) gibi bir şeydir.

//+------------------------------------------------------------------+
//|                                                       CBrain.mqh |
//|                               Copyright © 2013, Jordi Bassagañas |
//+------------------------------------------------------------------+
#include <..\Experts\NewsWatcher\CNewsContainer.mqh>
//+------------------------------------------------------------------+
//| CBrain Class                                                     |
//+------------------------------------------------------------------+
class CBrain
  {
protected:
   double               m_size;                 // The size of the positions
   int                  m_stopLoss;             // Stop loss
   int                  m_takeProfit;           // Take profit
   CNewsContainer       *m_news_container;      // The news container

public:
   //--- Constructor and destructor methods
                        CBrain(int stopLoss,int takeProfit,double size,string csv);
                        ~CBrain(void);
   //--- Getter methods
   double               GetSize(void);
   int                  GetStopLoss(void);
   int                  GetTakeProfit(void);
   CNewsContainer       *GetNewsContainer(void);
   //--- Setter methods
   void                 SetSize(double size);
   void                 SetStopLoss(int stopLoss);
   void                 SetTakeProfit(int takeProfit);
   //--- CBrain specific methods
   bool                 Init();
   void                 Deinit(void);
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CBrain::CBrain(int stopLoss,int takeProfit,double size,string csv)
  {
   m_size=size;
   m_stopLoss=stopLoss;
   m_takeProfit=takeProfit;
   m_news_container=new CNewsContainer(csv);   
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CBrain::~CBrain(void)
  {
   Deinit();
  }
//+------------------------------------------------------------------+
//| GetSize                                                          |
//+------------------------------------------------------------------+
double CBrain::GetSize(void)
  {
   return m_size;
  }
//+------------------------------------------------------------------+
//| GetStopLoss                                                      |
//+------------------------------------------------------------------+
int CBrain::GetStopLoss(void)
  {
   return m_stopLoss;
  }
//+------------------------------------------------------------------+
//| GetTakeProfit                                                    |
//+------------------------------------------------------------------+
int CBrain::GetTakeProfit(void)
  {
   return m_takeProfit;
  }
//+------------------------------------------------------------------+
//| GetNewsContainer                                                 |
//+------------------------------------------------------------------+
CNewsContainer *CBrain::GetNewsContainer(void)
  {
   return m_news_container;
  }
//+------------------------------------------------------------------+
//| SetSize                                                          |
//+------------------------------------------------------------------+
void CBrain::SetSize(double size)
  {
   m_size=size;
  }
//+------------------------------------------------------------------+
//| SetStopLoss                                                      |
//+------------------------------------------------------------------+
void CBrain::SetStopLoss(int stopLoss)
  {
   m_stopLoss=stopLoss;
  }
//+------------------------------------------------------------------+
//| SetTakeProfit                                                    |
//+------------------------------------------------------------------+
void CBrain::SetTakeProfit(int takeProfit)
  {
   m_takeProfit=takeProfit;
  }
//+------------------------------------------------------------------+
//| CBrain initialization                                            |
//+------------------------------------------------------------------+
bool CBrain::Init(void)
  {
// Initialization logic here...
   return true;
  }
//+------------------------------------------------------------------+
//| CBrain deinitialization                                          |
//+------------------------------------------------------------------+
void CBrain::Deinit(void)
  {
   delete(m_news_container);
   Print("CBrain deinitialization performed!");
  }
//+------------------------------------------------------------------+

CNewsWatcher temelde kapsayıcıda (gazete) saklanan haberleri sıra sıra okur. Bu sırada fiyatta güçlü bir ivmelenme varsa, piyasada bir emir verir.

Robot, lot alımı veya satımına dair reaktif bir şekilde programlanmıştır. Diyelim ki, güçlü bir yukarı yönlü hareket oluştuğunda, EA fiyatın geri çekileceğini varsayar ve dolayısıyla satış yapar. Benzer şekilde, güçlü bir aşağı yönlü hareket oluştuğunda, robot fiyatın kısa sürede geri çekileceğini düşünerek piyasada uzun bir pozisyon açar. Bu elbette geliştirilebilir; daha önce belirtildiği gibi, bu makalede yüksek ölçüde verimli bir otomatik haber yatırımcısı geliştirmek için yeterli alan yoktur, amaç sadece kendi geliştirmelerinizde ilerlemeye devam edebilmeniz için size teknik temel bilgileri sağlamaktır.

Robot on the Taff

Şekil 2. Robot on the Taff. Flickr üzerinde Creative Commons Lisansı kapsamında dağıtılan görüntü


1.3. Teknik Göstergeler için Nesne Yönelimli Bir Kapsayıcı


Bir kez daha, uygulamalarımızı kavram perspektifinden ele almaya karar verdiğimizden, yeni paradigmaya bağlı kalmak amacıyla teknik göstergeler için kendi nesne yönelimli sarmalayıcılarımızı programlamak ilginçtir. Bu şekilde, bu yapboz parçası her şeye çok daha iyi uymaktadır. Diyelim ki geliştirmemizin bu kısmında, orijinal haliyle pek de OO olmayan bu MQL5 ile daha rahat çalışabilmemiz için nesne yönelimli bir çerçeve gibi bir şey oluşturma avantajından yararlanıyoruz.

Bu noktada, MQL5 Standart Kitaplığından bahsetmek ilginç olacaktır. Bu kitaplık, son kullanıcılar için programları yazmayı (göstergeler, betikler, uzmanlar) kolaylaştırarak MQL5 dahili fonksiyonlarından çoğuna rahat erişim sağlamaktadır. Aslında, bazı Standart Kitaplık fonksiyonlarını bugünün alıştırmasında kullanacağız, çünkü belirtildiği gibi OO programlama bakış açısından bu şekilde çok daha rahat. Açık bir örnek, biraz sonra açıklayacağım haber kapsayıcıdır; burada, karmaşık türdeki özel nesne yönelimli haberlerimizi bilgisayarın RAM'inde saklamak için CarrayObj MQL5 sınıfını kullanacağız.

Lütfen bu konuya dair daha fazla bilgi edinmek için Standart Kitaplık başlıklı resmi belgelere göz atın ve göstergeler ile çalışmak için Standart Kitaplığın halihazırda bazı sınıflar ile birlikte geldiğini unutmayın. Bu makale, eğitim amacıyla bazı basit örnekler yoluyla nesne yönelimli materyaller ile çalışma gerekliliğini tartışmaktadır.

1.3.1. CTechIndicators, Teknik Göstergeler Kapsayıcısı
//+------------------------------------------------------------------+
//|                                              CTechIndicators.mqh |
//|                               Copyright © 2013, Jordi Bassagañas |
//+------------------------------------------------------------------+
#include <..\Experts\NewsWatcher\CMomentum.mqh>
//+------------------------------------------------------------------+
//| CTechIndicators Class                                            |
//+------------------------------------------------------------------+
class CTechIndicators
  {
protected:
   CMomentum               *m_momentum;
                  
public:
   //--- Constructor and destructor methods
                           CTechIndicators(void);
                           ~CTechIndicators(void);
   //--- Getter methods
   CMomentum               *GetMomentum(void);
   //--- CTechIndicators specific methods
   bool                 Init();
   void                 Deinit(void);
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+   
CTechIndicators::CTechIndicators(void)
  {
   m_momentum = new CMomentum; 
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+               
CTechIndicators::~CTechIndicators(void)
  {
   Deinit();
  }
//+------------------------------------------------------------------+
//| GetMomentum                                                      |
//+------------------------------------------------------------------+        
CMomentum* CTechIndicators::GetMomentum(void)
  {
   return m_momentum;
  }
//+------------------------------------------------------------------+
//| CTechIndicators initialization                                   |
//+------------------------------------------------------------------+
bool CTechIndicators::Init(void)
  {
// Initialization logic here...
   return true;
  }
//+------------------------------------------------------------------+
//| CTechIndicators deinitialization                                 |
//+------------------------------------------------------------------+
void CTechIndicators::Deinit(void)
  {
   delete(m_momentum);
   Print("CTechIndicators deinitialization performed!");
  }
//+------------------------------------------------------------------+
1.3.2. CMomentum, iMomentum için bir Nesne Yönelimli Sarmalayıcı
//+------------------------------------------------------------------+
//|                                                    CMomentum.mqh |
//|                               Copyright © 2013, Jordi Bassagañas |
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| CMomentum Class                                                  |
//+------------------------------------------------------------------+

class CMomentum
  {
protected:   
   int m_handler;
   double m_buffer[];
               
public:
   //--- Constructor and destructor methods
                           CMomentum(void);
                           ~CMomentum(void);
   //--- Getter methods
   int                     GetHandler(void);
   void                    GetBuffer(double &buffer[], int ammount);
   //--- Setter methods
   bool                    SetHandler(string symbol,ENUM_TIMEFRAMES period,int mom_period,ENUM_APPLIED_PRICE mom_applied_price);
   bool                    UpdateBuffer(int ammount);
  };
//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+   
CMomentum::CMomentum(void)
  {
   ArraySetAsSeries(m_buffer, true);   
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+               
CMomentum::~CMomentum(void)
  {
   IndicatorRelease(m_handler);
   ArrayFree(m_buffer);
  }
//+------------------------------------------------------------------+
//| GetHandler                                                       |
//+------------------------------------------------------------------+        
int CMomentum::GetHandler(void)
  {
   return m_handler;
  }
//+------------------------------------------------------------------+
//| GetBuffer                                                        |
//+------------------------------------------------------------------+
void CMomentum::GetBuffer(double &buffer[], int ammount)
  {
   ArrayCopy(buffer, m_buffer, 0, 0, ammount);
  }
//+------------------------------------------------------------------+
//| SetHandler                                                       |
//+------------------------------------------------------------------+      
bool CMomentum::SetHandler(string symbol,ENUM_TIMEFRAMES period,int mom_period,ENUM_APPLIED_PRICE mom_applied_price)
  {   
   if((m_handler=iMomentum(symbol,period,mom_period,mom_applied_price))==INVALID_HANDLE)
   {
      printf("Error creating Momentum indicator");
      return false;
   }
   return true;
  }
//+------------------------------------------------------------------+
//| UpdateBuffer                                                     |
//+------------------------------------------------------------------+   
bool CMomentum::UpdateBuffer(int ammount)
  {   
   if(CopyBuffer(m_handler, 0, 0, ammount, m_buffer) < 0)
   { 
      Alert("Error copying Momentum buffers, error: " , GetLastError());
      return false;
   }
   return true;
  }
//+------------------------------------------------------------------+


1.4. Haberler için bir Nesne Yönelimli Kapsayıcı

Haberler, kavram olarak, EA'mızın ilgilenmesi gereken temel bir parçadır. Bu kilit parçayı, bunu nesne yönelimli bir haber kapsayıcısına yerleştirmenin iyi bir fikir olduğu sonucuna varmak için, bir gazeteymiş gibi düşünebiliriz. Basitçe ifade edecek olursak, CNewsContainer adlı bu OO kapsayıcısı gazetedir. Ve tabii ki haberler içeren bir gazete hayal edebiliyorsak, aynı zamanda bizim nesneler etki alanımızda CNew olarak adlandırılan haber kavramını da modellememiz gerekir. Bu, gerçek dünyadaki haberleri temsil eden özel nesne yönelimli türümüzdür.

1.4.1. CNewsContainer, Haber Kapsayıcı

//+------------------------------------------------------------------+
//|                                               CNewsContainer.mqh |
//|                               Copyright © 2013, Jordi Bassagañas |
//+------------------------------------------------------------------+
#include <Files\FileTxt.mqh>
#include <Arrays\ArrayObj.mqh>
#include <..\Experts\NewsWatcher\CNew.mqh>
//+------------------------------------------------------------------+
//| CNewsContainer Class                                             |
//+------------------------------------------------------------------+
class CNewsContainer
  {
protected:
   string               m_csv;                  // The name of the csv file
   CFileTxt             m_fileTxt;              // MQL5 file functionality
   int                  m_currentIndex;         // The index of the next news to be processed in the container
   int                  m_total;                // The total number of news to be processed
   CArrayObj            *m_news;                // News list in the computer's memory, loaded from the csv file

public:
   //--- Constructor and destructor methods
                        CNewsContainer(string csv);
                        ~CNewsContainer(void);
   //--- Getter methods
   int                  GetCurrentIndex(void);
   int                  GetTotal(void);
   CNew                 *GetCurrentNew();
   CArrayObj            *GetNews(void);
   //--- Setter methods
   void                 SetCurrentIndex(int index);
   void                 SetTotal(int total);
   void                 SetNews(void);
   //--- CNewsContainer methods
   bool                 Init();
   void                 Deinit(void);
  };
//+------------------------------------------------------------------+
//| Constuctor                                                       |
//+------------------------------------------------------------------+
CNewsContainer::CNewsContainer(string csv)
  {
   m_csv=csv;
   m_news=new CArrayObj;
   SetNews();
   }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CNewsContainer::~CNewsContainer(void)
  {
   Deinit();
  }
//+------------------------------------------------------------------+
//| GetCurrentIndex                                                  |
//+------------------------------------------------------------------+
int CNewsContainer::GetCurrentIndex(void)
  {   
   return m_currentIndex;
  }
//+------------------------------------------------------------------+
//| GetTotal                                                         |
//+------------------------------------------------------------------+
int CNewsContainer::GetTotal(void)
  {   
   return m_total;
  }
//+------------------------------------------------------------------+
//| GetNews                                                          |
//+------------------------------------------------------------------+
CArrayObj *CNewsContainer::GetNews(void)
  {   
   return m_news;
  }
//+------------------------------------------------------------------+
//| GetCurrentNew                                                    |
//+------------------------------------------------------------------+
CNew *CNewsContainer::GetCurrentNew(void)
  {   
   return m_news.At(m_currentIndex);
  }
//+------------------------------------------------------------------+
//| SetCurrentIndex                                                  |
//+------------------------------------------------------------------+
void CNewsContainer::SetCurrentIndex(int index)
  {
   m_currentIndex=index;
  }
//+------------------------------------------------------------------+
//| SetTotal                                                         |
//+------------------------------------------------------------------+
void CNewsContainer::SetTotal(int total)
  {
   m_total=total;
  }
//+------------------------------------------------------------------+
//| SetNews                                                          |
//+------------------------------------------------------------------+
void CNewsContainer::SetNews(void)
  {
   //--- let's first init some vars!
   SetCurrentIndex(0);
   string sep= ";";
   ushort u_sep;
   string substrings[];   
   u_sep=StringGetCharacter(sep,0);   
   //--- then open and process the CSV file
   int file_handle=m_fileTxt.Open(m_csv, FILE_READ|FILE_CSV);
   if(file_handle!=INVALID_HANDLE)
   {
      while(!FileIsEnding(file_handle))
      {               
         string line = FileReadString(file_handle);         
         int k = StringSplit(line,u_sep,substrings);         
         CNew *current = new CNew(substrings[0],(datetime)substrings[1],substrings[2]);         
         m_news.Add(current);
      }
      FileClose(file_handle);
      //--- and finally refine and count the news
      m_news.Delete(0); // --- here we delete the CSV's header!
      SetTotal(m_news.Total());
   }
   else
   {
      Print("Failed to open the file ",m_csv);
      Print("Error code ",GetLastError());
   }   
  }
//+------------------------------------------------------------------+
//| CNewsContainer initialization                                    |
//+------------------------------------------------------------------+
bool CNewsContainer::Init(void)
  {
// Initialization logic here...
   return true;
  }
//+------------------------------------------------------------------+
//| CNewsContainer deinitialization                                  |
//+------------------------------------------------------------------+
void CNewsContainer::Deinit(void)
  {
   m_news.DeleteRange(0, m_total-1);
   delete(m_news);
   Print("CNewsContainer deinitialization performed!");
  }
//+------------------------------------------------------------------+

SetNews, CNewsContainer'ın en önemli yöntemidir. Bu yöntem CSV dosyasını okur ve bunu CNew türünde nesneler biçiminde bilgisayarın RAM'ine yükler. Bu arada, CSV dosyalarının data_folder\MQL5\FILES\ içinde saklanması gerektiğini hala söylemedim. SetNews içinde kullanılan fonksiyonları daha iyi anlamak için lütfen Dosya fonksiyonlarına bakın.

1.4.2. CNew, Haberin Kendisi

//+------------------------------------------------------------------+
//|                                                         CNew.mqh |
//|                               Copyright © 2013, Jordi Bassagañas |
//+------------------------------------------------------------------+
#include <Object.mqh>
//+------------------------------------------------------------------+
//| CNew Class                                                       |
//+------------------------------------------------------------------+
class CNew : public CObject
  {
protected:
   string            m_country;           // The country's name
   datetime          m_time_release;      // The date and time of the news
   string            m_name;              // The name of the news
   
public:
   //--- Constructor and destructor methods
                     CNew(string country,datetime time_release,string name);
                    ~CNew(void);
   //--- Getter methods
   string            GetCountry(void);
   datetime          GetTimeRelease(void);
   string            GetName(void);
   //--- Setter methods
   void              SetCountry(string country);
   void              SetTimeRelease(datetime time_release);
   void              SetName(string name);
   //--- CNew specific methods
   bool              Init();
   void              Deinit(void);
  };
//+------------------------------------------------------------------+
//| Constuctor                                                       |
//+------------------------------------------------------------------+
CNew::CNew(string country,datetime time_release,string name)
  {
   m_country=country;
   m_time_release=time_release;
   m_name=name;
  }
//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CNew::~CNew(void)
  {
   Deinit();
  }
//+------------------------------------------------------------------+
//| GetCountry                                                       |
//+------------------------------------------------------------------+
string CNew::GetCountry(void)
  {
   return m_country;
  }  
//+------------------------------------------------------------------+
//| GetTimeRelease                                                   |
//+------------------------------------------------------------------+
datetime CNew::GetTimeRelease(void)
  {
   return m_time_release;
  }
//+------------------------------------------------------------------+
//| GetName                                                          |
//+------------------------------------------------------------------+
string CNew::GetName(void)
  {
   return m_name;
  }
//+------------------------------------------------------------------+
//| SetCountry                                                       |
//+------------------------------------------------------------------+
void CNew::SetCountry(string country)
  {
   m_country=country;
  }
//+------------------------------------------------------------------+
//| SetTimeRelease                                                   |
//+------------------------------------------------------------------+
void CNew::SetTimeRelease(datetime timeRelease)
  {
   m_time_release=timeRelease;
  }
//+------------------------------------------------------------------+
//| SetName                                                          |
//+------------------------------------------------------------------+
void CNew::SetName(string name)
  {
   m_name=name;
  }
//+------------------------------------------------------------------+
//| CNew initialization                                              |
//+------------------------------------------------------------------+
bool CNew::Init(void)
  {
//--- initialization logic here...
   return true;
  }
//+------------------------------------------------------------------+
//| CNew deinitialization                                            |
//+------------------------------------------------------------------+
void CNew::Deinit(void)
  {
//--- deinitialization logic here...
   Print("CNew deinitialization performed!");
  }
//+------------------------------------------------------------------+


2. Backtesting ExpertNewsWatcher.mq5


2.1. Ekler

ExpertNewsWatcher aşağıdaki dosyalardan oluşur:

  • Enums.mqh
  • CBrain.mqh
  • CEvolution.mqh
  • CMomentum.mqh
  • CNew.mqh
  • CNewsContainer.mqh
  • CNewsWatcher.mqh
  • CTechIndicators.mqh
  • ExpertNewsWatcher.mq5
  • news_watcher.txt

2.2. Yükleme talimatları

İlk olarak, özel öğelerinizi saklamak için MQL5\Include\Mine klasörü oluşturmalı ve ardından Enums.mqh dosyasını buraya kopyalamalısınız. Bundan sonra, MQL5\Experts\NewsWatcher klasörü oluşturmalı ve aşağıdaki dosyaları kopyalamalısınız:

  • CBrain.mqh
  • CEvolution.mqh
  • CMomentum.mqh
  • CNew.mqh
  • CNewsContainer.mqh
  • CNewsWatcher.mqh
  • CTechIndicators.mqh
  • ExpertNewsWatcher.mq5

Çok önemli not! Son olarak, lütfen news_watcher.txtdosyasını alın, bunu news_watcher.csv olarak yeniden adlandırın ve data_folder\MQL5\FILES\ içine taşıyın. Bu belgenin yayınlandığı tarihte, MQL5 form gönderimi .csv dosyalarının gönderilmesine izin vermemektedir, ancak .txt dosyalarının gönderilmesine izin vermektedir.

Derlemeyi unutmayın. Bu noktadan itibaren, diğer herhangi bir Uzman Danışmanda yaptığınız gibi ExpertNewsWatcher'ı geriye dönük test edebilirsiniz.


2.3. Geriye dönük test sonuçları

ExpertNewsWatcher şu başlangıç giriş parametreleri ile çalıştırılmıştır:

  • Dönem = 1 Dakika
  • StopLoss = 400
  • TakeProfit = 600
  • LotSize = 0,01
  • CsvFile = news_watcher.csv

Başlangıçta, robotun kontrollü bir ortamda nasıl davrandığını görmek için zaman aralıklı şekilde bir dizi farazi haber içeren aşağıdaki sahte verileri kullandım. Bunun nedeni, bu dönemlerin belirlenmiş önkoşulları karşılamasıdır, yani bu zamanlarda momentum, alış veya satış eylemlerini tetikleyecek kadar büyüktür. Düşündüğünüz her şeyi test etmek için bu girişler sayfasını kullanabilirsiniz.

news_watcher.csv içinde saklanacak bazı sahte veriler:

Country;Time;Event
USD;2013.06.03 17:19:00;A. Momentum equals 100.47
USD;2013.06.13 17:09:00;B. Momentum equals 100.40
USD;2013.06.21 18:52:00;C. Momentum equals 100.19
USD;2013.07.01 17:32:00;D. Momentum equals 100.18 
USD;2013.07.08 15:17:00;E. Momentum equals 100.18
USD;2013.07.16 10:00:00;F. Momentum equals 99.81
USD;2013.07.24 09:30:00;G. Momentum equals 100.25


Sahte veriler ile elde edilen sonuçlar

Şekil 3. Sahte veriler ile elde edilen sonuçlar

Farazi haberleri içeren yukarıdaki grafik, bu robotun gerçek bir ortamda nasıl davranabileceğini anlamanıza yardımcı olacaktır. Lütfen DailyFX adresinden alınan aşağıdaki gerçek verileri alın, bunları news_watcher.csv içine yerleştirin ve ExpertNewsWatcher'ı yeniden çalıştırın.

news_watcher.csv içinde saklanacak bazı gerçek veriler:

Country;Time;Event
USD;2013.07.15 12:00:00;USD Fed's Tarullo Speaks on Banking Regulation in Washington 
USD;2013.07.15 12:30:00;USD Advance Retail Sales (JUN) and others
USD;2013.07.15 14:00:00;USD USD Business Inventories (MAY)
USD;2013.07.15 21:00:00;USD EIA Gasoline and Diesel Fuel Update
USD;2013.07.16 12:30:00;USD Several Consumer Price Indexes 
USD;2013.07.16 13:00:00;USD USD Net Long-term TIC Flows (MAY) & USD Total Net TIC Flows (MAY)
USD;2013.07.16 13:15:00;USD Industrial Production (JUN) and others
USD;2013.07.16 14:00:00;USD NAHB Housing Market Index (JUL)
USD;2013.07.16 18:15:00;USD Fed's George Speaks on Economic Conditions and Agriculture
USD;2013.07.22 12:30:00;USD Chicago Fed Nat Activity Index (JUN)
USD;2013.07.22 14:00:00;USD Existing Home Sales (MoM) (JUN) & Existing Home Sales (JUN)
USD;2013.07.22 21:00:00;USD EIA Gasoline and Diesel Fuel Update
USD;2013.07.23 13:00:00;USD House Price Index (MoM) (MAY)
USD;2013.07.23 14:00:00;USD Richmond Fed Manufacturing Index (JUL)
USD;2013.07.24 11:00:00;USD MBA Mortgage Applications (JUL 19)
USD;2013.07.24 12:58:00;USD Markit US PMI Preliminary (JUL)
USD;2013.07.24 14:00:00;USD USD New Home Sales (MoM) (JUN) & USD New Home Sales (JUN)
USD;2013.07.24 14:30:00;USD USD DOE U.S. Crude Oil Inventories (JUL 19) and others



Gerçek veriler ile elde edilen sonuçlar

Şekil 4. Gerçek veriler ile elde edilen sonuçlar

Bu basit haber işlemcisi yalnızca belirli bir zamanda gerçekleşen tek bir habere yanıt verebilir. Bu nedenle, örneğin 2013.07.15 12:30:00 olan belirli bir saatte birkaç haber meydana gelebilir. Belirli bir zamanda birkaç önemli haber meydana geliyorsa, lütfen CSV dosyasına tek bir giriş yazın.

Buna ek olarak, EA'nın gerçek veriler ile çalışırken piyasaya yalnızca üç işlemi girdiğini gözlemleyin. Bunun nedeni, zamanı aralıklı önceki farazi haberlerin aksine, gerçek hayatta bazı haberlerin üst üste gelmesidir. Robotumuz, halihazırda açık bir pozisyon varken gelen bir haberi yok sayarak, seriden gelen ilk işlemi ilk önce kapatacak şekilde planlanmıştır.

       double momentumBuffer[];
      
      GetTechIndicators().GetMomentum().GetBuffer(momentumBuffer, 2);
      
      //--- Number of seconds before the news releases. GMT +- timeWindow is the real time from which the robot starts 
      //--- listening to the market. For instance, if there is a news release programmed at 13:00 GMT you can set TimeWindow 
      //--- to 900 seconds so that the EA starts listening to the market fifteen minutes before that news release. 
      int timeWindow=600;
      
      CNew *currentNew = GetBrain().GetNewsContainer().GetCurrentNew();      
      int indexCurrentNew = GetBrain().GetNewsContainer().GetCurrentIndex();
            
      if(TimeGMT() >= currentNew.GetTimeRelease() + timeWindow)
      {
         GetBrain().GetNewsContainer().SetCurrentIndex(indexCurrentNew+1);
         return;
      }
      
      //--- is there any open position?
      if(!m_positionInfo.Select(_Symbol))
      {
         //--- if there is no open position, we try to open one
         bool timeHasCome = TimeGMT() >= currentNew.GetTimeRelease() - timeWindow && TimeGMT() <= currentNew.GetTimeRelease() + timeWindow;
             
         if(timeHasCome && momentumBuffer[0] > 100.10)
         {
            GetEvolution().SetStatus(SELL);
            GetBrain().GetNewsContainer().SetCurrentIndex(indexCurrentNew+1);
         }
         else if(timeHasCome && momentumBuffer[0] < 99.90)
         {
            GetEvolution().SetStatus(BUY);
            GetBrain().GetNewsContainer().SetCurrentIndex(indexCurrentNew+1);
         }
      }
      //--- if there is an open position, we let it work the mathematical expectation
      else 
      {
         GetEvolution().SetStatus(DO_NOTHING);         
      }  


Sonuç

Bu makale, size basit bir OO EA'nın sıfırdan nasıl oluşturulacağını gösteren ve nesne yönelimli programlamaya dair bazı ipuçları sağlayan Bir Diğer MQL5 OOP sınıfı makalesinin devamı niteliğinde olmuştur. Aynı anlayışla, bu metin de size kendi haber yatırımcılarınızı oluşturmanıza yardımcı olacak gerekli araçları sağlamıştır. OO tasarımlarımız ile rahatça çalışabilmemiz için, nesne yönelimli kapsayıcıların ve nesne yönelimli sarmalayıcıların uygulanmasını ele aldık. Ayrıca, dosya sistemi ile çalışmak için MQL5 Standart Kitaplığı ve MQL5 fonksiyonlarını da tartıştık.

MetaQuotes Ltd tarafından İngilizceden çevrilmiştir.
Orijinal makale: https://www.mql5.com/en/articles/719

Ekli dosyalar |
cbrain__2.mqh (4.82 KB)
cevolution__2.mqh (2.07 KB)
cmomentum.mqh (3.35 KB)
cnew.mqh (4.32 KB)
enums__2.mqh (0.92 KB)
news_watcher.txt (1.27 KB)
cnewscontainer.mqh (5.95 KB)
cnewswatcher.mqh (7.61 KB)
MQL5 Sihirbazı: EA'ya Herhangi bir Fiyattaki Bekleyen Emirleri Açması Nasıl Öğretilir? MQL5 Sihirbazı: EA'ya Herhangi bir Fiyattaki Bekleyen Emirleri Açması Nasıl Öğretilir?
Bu makale, mevcut fiyattan herhangi bir uzaklıkta olan bekleyen emirleri ayarlamanıza olanak sağlayan fonksiyonelliğin uygulanması için bir alım satım sinyali modülünün kodunun değiştirilmesi yöntemini açıklamaktadır: bu fiyat, önceki çubuğun Kapanış veya Açılış fiyatı veya hareketli ortalama değeri olabilir. Birçok seçenek vardır. Önemli olan, bekleyen bir emir için herhangi bir açılış fiyatı belirleyebilmenizdir. Bu makale, bekleyen emirler ile alım satım yapan yatırımcılar için faydalı olacaktır.
MQL5 Sihirbazı ve Hlaiman EA Oluşturucu Kullanarak Sinir Ağı EA'ları Oluşturma MQL5 Sihirbazı ve Hlaiman EA Oluşturucu Kullanarak Sinir Ağı EA'ları Oluşturma
Makale, MQL5 Sihirbazı ve Hlaiman EA Oluşturucu kullanarak otomatik sinir ağı EA'ları oluşturma yöntemini açıklar. Teorik bilgilerin tamamını öğrenmek ve kendi kodunuzu yazmak zorunda kalmadan nasıl kolay bir şekilde sinir ağları ile çalışmaya başlayabileceğinizi gösterir.
Kullanılabilir Teknolojiler Kokteyli ile MQL5 Müşterilerinizi Büyüleyin! Kullanılabilir Teknolojiler Kokteyli ile MQL5 Müşterilerinizi Büyüleyin!
MQL5, programcılara MetaTrader ortamında istedikleri her şeyi yapabilecekleri eksiksiz bir fonksiyonlar ve nesne yönelimli API seti sağlar. Bununla birlikte, Web Teknolojisi günümüzde çok özel bir şey yapmanız gerektiğinde, müşterilerinizi farklı bir şeyle hayrete düşürmek istediğinizde veya basitçe MT5 Standart Kitaplığının belirli bir bölümünde ustalaşmak için yeterli zamanınız olmadığında imdadınıza yetişecek son derece çok yönlü bir araçtır. Bugünkü alıştırma, inanılmaz bir teknoloji kokteyli oluştururken aynı anda geliştirme zamanınızı nasıl yönetebileceğinize dair pratik bir örnek ile size yol gösterir.
Bir Diğer MQL5 OOP Sınıfı Bir Diğer MQL5 OOP Sınıfı
Bu makale, bir teorik alım satım fikri tasarlamaktan bu fikri deneysel dünyada gerçek hale getiren bir MQL5 EA programlamaya kadar bir Nesne Yönelimli Uzman Danışmanı sıfırdan nasıl oluşturacağınızı gösterir. Bana göre, yaparak öğrenmek başarılı olmak için sağlam bir yaklaşımdır, bu yüzden fikirlerinizi nihai olarak Forex robotlarınızı kodlamak için nasıl sıraya dizeceğinizi görmeniz için pratik bir örnek göstereceğim. Ayrıca amacım sizi OO ilkelerine bağlı kalmaya davet etmek.