"MQL5 Sihirbazı: Alım Satım Sinyalleri Modülü Nasıl Oluşturulur" makalesi için tartışma - sayfa 6

 
Karputov Vladimir:
Ya da bir para yönetimi modülü. Hangisini seçeceğinize daha detaylı bakmanız gerekiyor.

Konsept çok net değil. Pozisyon açmak için sinyaller var, ancak bunları kapatmak için de sinyaller var. Oylama vb. kullanmak mümkün olabilir ve tüm bunlar takip etmeye ek olarak.

Ve temel sınıflar ne sıklıkla değişir? Sinyal modülümü sihirbazın önceki sürümüyle yazmış olsaydım, şimdi yeniden tasarlamam gerekirdi.

Sadece merak ediyorum, bu sihirbazı ve Uzman Danışmanlar temel sınıflarını ciddi olarak kullanan var mı yoksa sadece kendi başına bir şey yapmak istemeyen tembel insanlar için mi?

 
Karputov Vladimir:
Ya da bir para yönetimi modülü. Tam olarak neyi seçeceğinize daha detaylı bakmanız gerekiyor.

Üzgünüm, OOP konusunda iyi değilim, anlamama yardımcı olabilir misiniz?

Burada СMySignal.mqh adında bir ticaret sinyalleri modülü yaptım. Şimdi kendi kapanış sinyallerimi uygulamak istiyorum. Bunun için kendi sermaye yönetimi modülümü CMyMoney.mqh oluşturuyorum çünkü CExpert'in böyle bir çağrısı var:

protected:
  CExpertMoney     *m_money;

bool CExpert::CheckClose(void)

  {
   double lot;
//--- position must be selected before call
   if((lot=m_money.CheckClose(GetPointer(m_position)))!=0.0)
      return(CloseAll(lot));

Ancak kapanış mantığında CMySignal sınıfının yöntemlerini kullanmak istiyorum, tüm hesaplamaları CMyMoney'de tekrar yapmak istemiyorum. Bu yüzden CMyMoney'de şöyle bir şey yazıyorum:

class CMyMoney : public CExpertMoney

protected:

   //--- input parameters
   virtual bool      CheckCloseLong(void);
   virtual bool      CheckCloseShort(void);

   CMySignal         *filter0;

...

double CMyMoney::CheckClose(CPositionInfo *position)
  {
   double lot;
   lot=position.Volume();
   if(position.PositionType()==POSITION_TYPE_BUY)
     {
      //--- check the possibility of closing the long position
      if(filter0.CheckCloseLong(lot))
         Print(__FUNCTION__+": close long position signal detected. Lot to be closed ",lot); 
     }
   else
     {
      //--- check the possibility of closing the short position
      if(filter0.CheckCloseShort(lot))
         Print(__FUNCTION__+": close short position signal detected. Lot to be closed ",lot);
     }
   return(lot);
  }


Ve tüm kapanış mantığını CMySignal sınıfına taşıyorum:

class CMySignal : public CExpertSignal

public:

   virtual bool      CheckCloseLong(double &lot);
   virtual bool      CheckCloseShort(double &lot);

bool CMySignal::CheckCloseLong(double &lot)

  {

   //логика закрытия Long

  }

bool CMySignal::CheckCloseShort(double &lot)

  {

   //логика закрытия Short

  }

Ancak, zaten oluşturulmuş bir nesneyle değil, yeni bir filter0 nesnesiyle uğraştığım ortaya çıkıyor. Bunun için verileri yeniden başlatmam gerekiyor (göstergeler vb.). CMySignal sınıfının zaten var olan nesnesine nasıl erişebilirim? Umarım kendimi açıkça ifade edebilmişimdir =)

Tüm bunlar Sihirbaz aracılığıyla standart bir şekilde çalışmalı, bu yüzden herhangi bir temel sınıfı değiştirmiyorum. Tüm değişiklikler yalnızca alım satım sinyallerimde ve para yönetimi modüllerimde mümkündür.

 
t101:

Üzgünüm, OOP konusunda iyi değilim, anlamama yardımcı olabilir misiniz?

СMySignal.mqh adında bir ticaret sinyalleri modülü yaptım. Şimdi kendi kapanış sinyallerimi uygulamak istiyorum. Bunun için kendi sermaye yönetimi modülümü CMyMoney.mqh oluşturuyorum çünkü CExpert'in böyle bir çağrısı var:

protected:
  CExpertMoney     *m_money;

bool CExpert::CheckClose(void)

  {
   double lot;
//--- position must be selected before call
   if((lot=m_money.CheckClose(GetPointer(m_position)))!=0.0)
      return(CloseAll(lot));

Ancak kapanış mantığında CMySignal sınıfının yöntemlerini kullanmak istiyorum, tüm hesaplamaları CMyMoney'de tekrar yapmak istemiyorum. Bu yüzden CMyMoney'de şöyle bir şey yazıyorum:

class CMyMoney : public CExpertMoney

protected:

   //--- input parameters
   virtual bool      CheckCloseLong(void);
   virtual bool      CheckCloseShort(void);

   CMySignal         *filter0;

...

double CMyMoney::CheckClose(CPositionInfo *position)
  {
   double lot;
   lot=position.Volume();
   if(position.PositionType()==POSITION_TYPE_BUY)
     {
      //--- check the possibility of closing the long position
      if(filter0.CheckCloseLong(lot))
         Print(__FUNCTION__+": close long position signal detected. Lot to be closed ",lot); 
     }
   else
     {
      //--- check the possibility of closing the short position
      if(filter0.CheckCloseShort(lot))
         Print(__FUNCTION__+": close short position signal detected. Lot to be closed ",lot);
     }
   return(lot);
  }


Ve tüm kapanış mantığını CMySignal sınıfına taşıyorum:

class CMySignal : public CExpertSignal

public:

   virtual bool      CheckCloseLong(double &lot);
   virtual bool      CheckCloseShort(double &lot);

bool CMySignal::CheckCloseLong(double &lot)

  {

   //логика закрытия Long

  }

bool CMySignal::CheckCloseShort(double &lot)

  {

   //логика закрытия Short

  }

Ancak, zaten oluşturulmuş bir nesneyle değil, yeni bir filter0 nesnesiyle uğraştığım ortaya çıkıyor. Bunun için verileri yeniden başlatmam gerekiyor (göstergeler vb.). CMySignal sınıfının zaten var olan nesnesine nasıl erişebilirim? Umarım kendimi açıkça ifade edebilmişimdir =)

Tüm bunlar Sihirbaz aracılığıyla standart bir şekilde çalışmalı, bu yüzden herhangi bir temel sınıfı değiştirmiyorum. Tüm değişiklikler yalnızca alım satım sinyallerimde ve para yönetimi modüllerimde mümkündür.

İkinci "sayfa" ile ilgili bir sorum var - neden para yönetimi modülüne"CMySignal *filter0;" ekliyorsunuz?
 
Karputov Vladimir:
İkinci "sayfa" hakkında bir sorum var - neden para yönetimi modülüne"CMySignal *filter0;" ekliyorsunuz?

filter0, ticaret sinyalleri modülüm CMySignal'ın bir sınıf nesnesidir. Uzman Danışmanın ana dosyasında oluşturulur:

CMySignal *filter0=new CMySignal;

Tüm kapanış hesaplamalarını sinyal modülüme aktarmak için para yönetimi modülünden ona erişmeye çalışıyorum. Kendi kapanış mantığımı uygulamanın başka bir yolunu göremiyorum.
 
t101:

filter0, ticaret sinyalleri modülüm CMySignal'ın bir sınıf nesnesidir. Ana EA dosyasında oluşturulur:

CMySignal *filter0=new CMySignal;

Tüm kapanış hesaplamalarını sinyal modülüme aktarmak için para yönetimi modülünden erişmeye çalışıyorum. Kendi kapanış mantığımı uygulamanın başka bir yolunu göremiyorum.

İşaretçiyi ana sinyale sinyal modülüne aktarma uygulamasına bakın(MQL5 Sihirbazı: Bir Uzman Danışmana bekleyen emirleri herhangi bir fiyattan açmayı öğretme):

Fikir uygulama şemamıza göre, ana sinyale işaretçinin saklanacağı dahili bir değişken bildirmek gerekir.

Bu değişkenin dahili olması gerektiğinden (kapsamı yalnızca alım satım sinyali oluşturucu sınıfının içinde olacak şekilde), bunu bir sonraki kod bloğuna ekleyeceğiz:

protected:
   CiEnvelopes       m_env;          // nesne-göstergesi
   //--- ayarlanmış parametreler
   int               m_ma_period;    // göstergenin "ortalama alma süresi" parametresi
   int               m_ma_shift;     // göstergenin "zaman kayması" parametresi
   ENUM_MA_METHOD    m_ma_method;     // göstergenin "ortalama alma yöntemi" parametresi
   ENUM_APPLIED_PRICE m_ma_applied;    // göstergenin "ortalama nesnesi" parametresi
   double            m_deviation;    // göstergenin "sapma" parametresi
   //--- piyasa modellerinin "ağırlıkları" (0-100)
   int               m_pattern_0;      // model 0
   CExpertSignal    *m_signal;         // ana sinyale referans saklayın

Ayrıca kodda kullanılmayacak değişkenleri kaldırdığımı da unutmayın.

Ana sinyalin işaretçisini saklamak için kullanılacak yöntemi başka bir kod bloğunda bildireceğiz - "ana sinyalin işaretçisini ayarlama yöntemi". Bazı gereksiz yöntemler de kaldırılmıştır.

Belki de ihtiyacınız olan budur. Sermaye yönetimi modülüne yalnızca ana sinyalin işaretçisi aktarılacaktır.

 
Karputov Vladimir:

İşaretçiyi ana sinyale sinyal modülüne geçirme uygulamasına bakın(MQL5 Sihirbazı: Uzman Danışmana bekleyen emirleri herhangi bir fiyattan açmayı öğretme):

Belki de ihtiyacınız olan şey budur. Para yönetimi modülüne yalnızca ana sinyalin işaretçisi aktarılacaktır.

CExpertSignal sınıfının mirasçısı olan sinyalime bir işaretçiye ihtiyacım varsa neden ana sinyale bir işaretçiye ihtiyacım var? Bunu CExpertMoney'nin soyundan gelen para yönetimi modülümde istiyorum.
 
t101:
CExpertSignal sınıfının bir torunu olan sinyalime bir işaretçi istiyorsam neden baş sinyale bir işaretçiye ihtiyacım var? Bunu CExpertMoney'nin mirasçısı olan para yönetimi modülümde istiyorum.

Tamam. Diğer tarafa geçelim. Para yönetimi modülünüzde, aşağıdaki gibi bir değişken bildirmeniz gerekir:

CMySignal    *m_signal;         // sinyalinize bir referans saklayın

ve bunun gibi bir yöntem:

   //--- ana sinyale işaretçi ayarlama yöntemi
   virtual bool      InitSignal(СMySignal *filter=NULL);

ve uygulanması

//+------------------------------------------------------------------+
//| Başlatma sinyali nesnesi|
//+------------------------------------------------------------------+
bool CMyMoney::InitSignal(СMySignal *filter)
  {
   m_signal=filter;
   return(true);
  }

Şimdi sinyalinize para yönetimi modülünden şu yolla erişmeyi deneyebilirsiniz

m_signal.метод вашего модуля сигналов
 
Karputov Vladimir:

Pekâlâ. Diğer tarafa geçelim. Para yönetimi modülünüzde, aşağıdaki gibi bir değişken bildirmeniz gerekir:

ve bu yöntem:

ve uygulanması

Şimdi para yönetimi modülünden sinyalime şu yolla erişmeyi deneyebilirim

Sinyal modülümün bir yöntemini çağırırken geçersiz işaretçi erişimi
m_signal.метод вашего модуля сигналов
InitSignal önceden bir yerde çağrılmalı mı?
 
t101:
Sinyal modülümün bir yöntemini çağırırken geçersiz işaretçi erişimi
InitSignal önceden bir yerde çağrılmalı mı?
Elbette "InitSignal" daha önce çağrılmalıdır: EA'nın OnInit()'inden, para yönetimi modülünün başlatma bloğunun sonunda.
 
Karputov Vladimir:
Elbette "InitSignal "ı daha önce çağırmamız gerekiyor: EA'nın OnInit()'inden, para yönetimi modülünün başlatma bloğunun sonunda.
Bunu manuel olarak OnInit()'e eklemeli miyim? Yani Sihirbaz aracılığıyla istediğimi yapamaz mıyım?