Discussão do artigo "Padrões de projeto no MQL5 (Parte 4): Padrões comportamentais 2"

 

Novo artigo Padrões de projeto no MQL5 (Parte 4): Padrões comportamentais 2 foi publicado:

Com este artigo concluímos a série sobre padrões de projeto na área de software. Já mencionei que existem três tipos de padrões de projeto: criacionais, estruturais e comportamentais. Finalizaremos os padrões comportamentais restantes, que ajudarão a definir a maneira de interação entre objetos, de modo a tornar nosso código mais limpo.

Lembrete (Memento)

O padrão pode ser usado para externalizar o estado de um objeto, a fim de fornecer a função de rollback (desfazer). Ele também é conhecido como token.

O que o padrão faz?

Podemos aplicar o padrão quando precisamos salvar um instantâneo do estado de um objeto que será restaurado posteriormente, e quando a interface direta para obter o estado pode revelar detalhes de execução e violar a encapsulação do objeto. Assim, o padrão capturará e exportará o estado do objeto para posterior restauração. Abaixo está o diagrama da estrutura deste padrão, mostrando como ele pode funcionar:

Memento

Autor: Mohamed Abdelmaaboud

 

Obrigado por esse excelente artigo.

Acho que implementei o padrão de estratégia em um Expert Advisor, mas talvez de uma forma diferente

Isso poderia dar um exemplo mais prático para a mente de nossos amados leitores e, para mim, talvez eu gostasse de receber seu feedback se cometi erros conceituais:

Vou simplificar o processo aqui:
o Expert em si é um objeto e se torna o Contexto:

  • Tenho um Enum para poder escolher a estratégia (por exemplo, STRATEGY_RSI, STRATEGY_MA,...)
  • Tenho uma instrução switch no OnInit(), no enum de estratégias, e, dependendo do resultado, eu

switch(strategyName)
        {
         case STRATEGY_RSI :
            m_strategy = new Strategy_RSI();
            break;
         case STRATEGY_MA :
            m_strategy = new Strategy_MA();
            break;
         default:
            break;
}

  • Defino os parâmetros de entrada na estratégia por meio de um objeto de parâmetro (como mqlparams)
[...]
// adicionar os parâmetros de sinal à estratégia por meio do método expert
Expert.AddParameterObject(signal_RSI_Params); // signal_RSI_Params é o objeto de parâmetro que contém os parâmetros de entrada

//detalhe do método AddParameterObject (simplificado):
bool CExpert::AddParameterObject(CParameter & parameter)
  {
         if(!m_strategy.AddParameterObject(parameter))
           {
            return(false);
           }
     }
   return true;
  }

// adicionar os parâmetros genéricos de especialista.
Expert.InitStrategyParameters(expert_1_Params);

//detalhe do método (simplificado) :
bool CExpert::InitStrategyParameters(CParameter & expertParameters)
  {
// 
   if(!m_strategy.InitStrategyParameters(expertParameters))
     {
     [...]
      return false;
     }
   return true;
  }


  • Todas as estratégias implementam os mesmos métodos (abrir um sinal, fechar uma negociação, etc.)
  • Todas as estratégias podem carregar um sinal ou seus indicadores personalizados

Na função OnTick do especialista, chamo os métodos genéricos da estratégia.

bool CExpert::CheckOpenLong(void)
  {
    [...]
    if(true == m_strategy.CheckOpenLong([...]))
     {
      [...]
     }
    [...]
}


Está funcionando muito bem, pois também posso testar várias estratégias/otimizações com o mesmo especialista.

A única coisa que nunca descobri, além de colocar os parâmetros de entrada em um arquivo separado, é como carregar dinamicamente os parâmetros de entrada de acordo com o que o usuário está escolhendo como esse parâmetro de entrada específico (ou seja, a entrada da estratégia).


Gostaria de receber seu feedback sobre a forma como implementei, se é um padrão de estratégia ou um híbrido, o que poderia ser melhorado?

E você tem alguma ideia de como poderíamos ter (acho que não é possível com o MT5) parâmetros de entrada contextuais dinâmicos?


Muito obrigado

Didma

 

muito instrutivo

 

Por que as funções com a mesma funcionalidade têm nomes diferentes
, por exemplo, aqui


void Memento::SetState(string state)
  {
   m_state=state;
  }
  
  
void Originator::State(string state)
  {
   m_state=state;
  }