기고글 토론 "MQL5 마법사: 신호 거래 모듈을 만드는 방법" - 페이지 6

 
Karputov Vladimir:
또는 자금 관리 모듈. 어느 것을 선택할지 더 자세히 살펴볼 필요가 있습니다.

개념이 명확하지 않습니다. 포지션 오픈 신호가 있지만 포지션 청산 신호도 있습니다. 투표 등을 사용할 수 있으며이 모든 것은 후행 외에도 가능합니다.

그리고 기본 클래스는 얼마나 자주 변경되나요? 이전 버전의 마법사로 시그널 모듈을 작성했다면 지금 다시 설계해야 할 것 같습니다.

이 마법사와 전문가 조언자 기본 클래스를 진지하게 사용하는 사람이 있는지, 아니면 손으로 아무것도 하기 싫은 게으른 사람만 사용하는 것인지 궁금합니다.

 
Karputov Vladimir:
또는 자금 관리 모듈. 정확히 무엇을 선택해야하는지 더 자세히 살펴 봐야합니다.

죄송합니다, 저는 OOP에 능숙하지 않은데 이해하도록 도와 주시겠습니까?

여기에서는 СMySignal.mqh라는 거래 신호 모듈을 만들었습니다. 이제 나만의 종가 신호를 구현하고 싶습니다. 이를 위해 CExpert에 그러한 호출이 있기 때문에 나만의 자본 관리 모듈 CMyMoney.mqh를 만듭니다:

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));

하지만 종가 로직에서 CMySignal 클래스의 메서드를 사용하고 싶고 CMyMoney에서 모든 계산을 다시 수행하고 싶지 않습니다. 그래서 CMyMoney에서 다음과 같이 작성합니다:

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);
  }


그리고 모든 클로징 로직을 CMySignal 클래스로 이동합니다:

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

  }

하지만 이미 생성된 개체가 아니라 새로운 filter0 개체를 다루고 있다는 것이 밝혀졌습니다. 이에 대한 데이터(표시기 등)를 다시 초기화해야 합니다. 이미 존재하는 CMySignal 클래스의 객체에 액세스하려면 어떻게 해야 하나요? 내가 명확하게 설명했기를 바랍니다 =)

이 모든 것은 마법사를 통해 표준 방식으로 작동해야하므로 기본 클래스를 변경하지 않습니다. 모든 변경은 내 거래 신호 및 자금 관리 모듈에서만 가능합니다.

 
t101:

죄송하지만 저는 OOP에 능숙하지 않은데 이해하도록 도와주실 수 있나요?

СMySignal.mqh라는 거래 신호 모듈을 만들었습니다. 이제 나만의 종가 신호를 구현하고 싶습니다. 이를 위해 CExpert에 그러한 호출이 있기 때문에 나만의 자본 관리 모듈 CMyMoney.mqh를 만듭니다:

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));

하지만 종가 로직에서 CMySignal 클래스의 메서드를 사용하고 싶고 CMyMoney에서 모든 계산을 다시 수행하고 싶지 않습니다. 그래서 CMyMoney에서 다음과 같이 작성합니다:

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);
  }


그리고 모든 클로징 로직을 CMySignal 클래스로 이동합니다:

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

  }

하지만 이미 생성된 개체가 아니라 새로운 filter0 개체를 다루고 있다는 것이 밝혀졌습니다. 이에 대한 데이터(표시기 등)를 다시 초기화해야 합니다. 이미 존재하는 CMySignal 클래스의 객체에 액세스하려면 어떻게 해야 하나요? 내가 명확하게 설명했기를 바랍니다 =)

이 모든 것은 마법사를 통해 표준 방식으로 작동해야하므로 기본 클래스를 변경하지 않습니다. 모든 변경은 내 거래 신호 및 자금 관리 모듈에서만 가능합니다.

두 번째 "시트"에 대해 질문이 있습니다 - 자금 관리 모듈에"CMySignal *필터0;"을 삽입하는 이유는 무엇입니까?
 
Karputov Vladimir:
두 번째 "시트"에 대해 질문이 있습니다 - 자금 관리 모듈에"CMySignal *필터0;"을 삽입하는 이유는 무엇입니까?

filter0은 내 트레이딩 신호 모듈 CMySignal의 클래스 객체입니다. 이 객체는 Expert Advisor의 메인 파일에 생성됩니다:

CMySignal *filter0=new CMySignal;

모든 종가 계산을 신호 모듈로 전송하기 위해 자금 관리 모듈에서 액세스하려고 합니다. 나만의 마감 로직을 구현하는 다른 방법이 보이지 않습니다.
 
t101:

filter0은 내 트레이딩 신호 모듈 CMySignal의 클래스 객체입니다. 기본 EA 파일에 생성됩니다:

CMySignal *filter0=new CMySignal;

자금 관리 모듈에서 액세스하여 모든 종가 계산을 신호 모듈로 전송하려고 합니다. 나만의 마감 로직을 구현하는 다른 방법이 보이지 않습니다.

주 신호에 대한 포인터를 신호 모듈로 전송하는 구현을 살펴보세요(MQL5 마법사: 전문가 고문에게 어떤 가격에서든 지정가 주문을 열도록 가르치는 방법):

아이디어 구현 계획에 따르면 주 신호에 대한 포인터가 저장될 내부 변수를 선언해야 합니다.

이 변수는 내부 변수(트레이딩 신호 생성기 클래스 내에서만 범위가 있는)여야 하므로 다음 코드 블록에 추가하겠습니다:

protected:
   CiEnvelopes       m_env;          // object-indicator
   //--- 조정된 매개변수
   int               m_ma_period;    // 지표의 "평균화 기간" 매개변수
   int               m_ma_shift;     // 인디케이터의 "시간 이동" 매개변수
   ENUM_MA_METHOD    m_ma_method;     // 표시기의 "평균화 방법" 매개 변수
   ENUM_APPLIED_PRICE m_ma_applied;    // 지표의 "평균화 대상" 매개 변수
   double            m_deviation;    // 표시기의 "편차" 매개 변수
   //--- 시장 모델의 "가중치"(0-100)
   int               m_pattern_0;      // 모델 0
   CExpertSignal    *m_signal;         // 메인 신호에 대한 참조 저장

또한 코드에서 사용되지 않을 변수는 제거했습니다.

메인 신호에 대한 포인터를 저장하는 데 사용할 메서드를 다른 코드 블록에 "메인 신호에 대한 포인터 설정 방법"으로 선언합니다. 일부 불필요한 메소드도 제거되었습니다.

아마도 이것이 여러분에게 필요한 것일 것입니다. 주 신호에 대한 포인터만 자본 관리 모듈로 전달됩니다.

 
Karputov Vladimir:

주 신호에 대한 포인터를 신호 모듈에 전달하는 구현을 살펴보세요(MQL5 마법사: 전문가 조언자에게 어떤 가격에서든 지정가 주문을 열도록 가르치는 방법):

아마도 이것이 필요한 것입니다. 주 신호에 대한 포인터만 자금 관리 모듈로 전달됩니다.

내 신호에 대한 포인터가 필요한데 왜 메인 신호에 대한 포인터, 즉 CExpertSignal 클래스의 상속자가 필요한가요? 내 자금 관리 모듈, 즉 CExpertMoney의 후손에 포인터가 필요하기 때문입니다.
 
t101:
내 신호에 대한 포인터, 즉 CExpertSignal 클래스의 자손이 필요한데 왜 헤드 신호에 대한 포인터가 필요한가요? 내 자금 관리 모듈, 즉 CExpertMoney의 상속자에서 이 포인터를 원합니다.

좋아요. 반대편으로 가보겠습니다. 자금 관리 모듈에서 다음과 같은 변수를 선언해야 합니다:

CMySignal    *m_signal;         // 신호에 대한 참조 저장

그리고 다음과 같은 메서드를 선언해야 합니다:

   //--- 메인 신호에 포인터를 설정하는 방법
   virtual bool      InitSignal(СMySignal *filter=NULL);

그리고 그 구현

//+------------------------------------------------------------------+
//| 초기화 신호 객체|
//+------------------------------------------------------------------+
bool CMyMoney::InitSignal(СMySignal *filter)
  {
   m_signal=filter;
   return(true);
  }

이제 다음을 통해 자금 관리 모듈에서 신호에 액세스할 수 있습니다.

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

좋아요. 반대편으로 가보겠습니다. 자금 관리 모듈에서 다음과 같은 변수를 선언해야 합니다:

그리고 이 메서드:

그리고 그 구현

이제 다음을 통해 자금 관리 모듈에서 내 신호에 액세스하려고 시도 할 수 있습니다.

내 신호 모듈의 메서드를 호출 할 때 잘못된 포인터 액세스
m_signal.метод вашего модуля сигналов
InitSignal을 미리 어딘가에서 호출해야합니까?
 
t101:
내 신호 모듈
InitSignal의 메서드를 호출할 때 포인터 액세스가 잘못되었습니다. 미리 어딘가에서 호출해야 하나요?
물론 자금 관리 모듈의 초기화 블록이 끝날 때 EA의 OnInit()에서 "InitSignal"을 먼저 호출해야 합니다.
 
Karputov Vladimir:
물론 자금 관리 모듈의 초기화 블록이 끝날 때 EA의 OnInit()에서 "InitSignal"을 더 일찍 호출해야 합니다.
OnInit()에 수동으로 추가해야 하나요? 마법사를 통해 원하는 작업을 할 수 없나요?