Discussão do artigo "LifeHack para traders: preparemos "fast-food" de indicadores" - página 12

 
fxsaber:

Os indicadores padrão (são os únicos discutidos no artigo) são armazenados em cache de forma elementar! Porque todos os parâmetros de entrada são conhecidos.

É difícil apenas escrever uma função hash universal. Mas isso não foi exigido no artigo. Ele trata do caso mais simples. E mesmo para ele não há função hash.

AmostraMACD 4 a 5 MQL4 style.mq5


Sem cache

i = 0 Pass = 0 OnTester = 15.070 s.: Count = 9753093, 647186.0 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1755
i = 1 Pass = 1 OnTester = 14.969 s.: Count = 9753093, 651552.7 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1755


Com cache estúpido

i = 0 Pass = 0 OnTester = 11.073 s.: Count = 9753093, 880799.5 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1755
i = 1 Pass = 1 OnTester = 11.007 s.: Count = 9753093, 886080.9 unit/sec, Agent = C:\Program Files\Alpari Limited MT5\Tester\Agent-127.0.0.1-3000 build = 1755


25% mais rápido se você não fizer nenhuma brincadeira (de frente). A crítica à "ineficiência" da abordagem apresentada é justificada.

 
Você pode me mostrar o código?
 
Rashid Umarov:
Você pode mostrar o código?
template <typename T>
struct HANDLE
{
private:  
  int Handle;
  
  T Inputs;

public:  
  HANDLE() : Handle(INVALID_HANDLE)
  {
  }
  
  bool operator ==( const T &Inputs2 ) const
  {
    return(this.Inputs == Inputs2);
  }
  
  void operator =( const T &Inputs2 )
  {
    this.Inputs = Inputs2;
  }
  
  int GetHandle()
  {
    return((this.Handle != INVALID_HANDLE) ? this.Handle : (this.Handle = this.Inputs.GetHandle()));
  }
};

template <typename T>
int GetHandle( HANDLE<T> &Handles[], const T &Inputs )
{
  const int Size = ArraySize(Handles);
  
  for (int i = 0; i < Size; i++)
    if (Handles[i] == Inputs)
      return(Handles[i].GetHandle());

  ArrayResize(Handles, Size + 1);
  Handles[Size] = Inputs;
  
  return(Handles[Size].GetHandle());
}

struct MACD
{
  string             symbol;
  ENUM_TIMEFRAMES    period;
  int                fast_ema_period;
  int                slow_ema_period;
  int                signal_period;
  ENUM_APPLIED_PRICE applied_price;
  
  MACD( void )
  {
  }
  
  MACD( const string             &isymbol,
        const ENUM_TIMEFRAMES    &iperiod,
        const int                &ifast_ema_period,
        const int                &islow_ema_period,
        const int                &isignal_period,
        const ENUM_APPLIED_PRICE &iapplied_price ) : 
        symbol((isymbol == NULL) || (isymbol == "") ? _Symbol : isymbol),
        period(iperiod == PERIOD_CURRENT ? ::Period() : iperiod),
        fast_ema_period(ifast_ema_period),
        slow_ema_period(islow_ema_period),
        signal_period(isignal_period),
        applied_price(iapplied_price)     
  {
  }
  
  int GetHandle( void ) const
  {
    return(::iMACD(this.symbol, this.period, this.fast_ema_period, this.slow_ema_period, this.signal_period, this.applied_price));
  }
  
  bool operator ==( const MACD &Inputs ) const
  {
    return((this.symbol == Inputs.symbol) &&
           (this.period == Inputs.period) &&
           (this.fast_ema_period == Inputs.fast_ema_period) &&
           (this.slow_ema_period == Inputs.slow_ema_period) &&
           (this.signal_period == Inputs.signal_period) &&
           (this.applied_price == Inputs.applied_price));
  }  
};

struct MA
{
  string             symbol;
  ENUM_TIMEFRAMES    period;
  int                ma_period;
  int                ma_shift;
  ENUM_MA_METHOD     ma_method;
  ENUM_APPLIED_PRICE applied_price;
  
  MA( void )
  {
  }
  
  MA( const string             &isymbol,
      const ENUM_TIMEFRAMES    &iperiod,
      const int                &ima_period,
      const int                &ima_shift,
      const ENUM_MA_METHOD     &ima_method,
      const ENUM_APPLIED_PRICE &iapplied_price ) :
      symbol((isymbol == NULL) || (isymbol == "") ? _Symbol : isymbol),
      period(iperiod == PERIOD_CURRENT ? ::Period() : iperiod),
      ma_period(ima_period),
      ma_shift(ima_shift),
      ma_method(ima_method),
      applied_price(iapplied_price)
  {
  }
  
  int GetHandle( void ) const
  {
    return(::iMA(this.symbol, this.period, this.ma_period, this.ma_shift, this.ma_method, this.applied_price));
  }
  
  bool operator ==( const MA &Inputs ) const
  {
    return((this.symbol == Inputs.symbol) &&
           (this.period == Inputs.period) &&
           (this.ma_period == Inputs.ma_period) &&
           (this.ma_shift == Inputs.ma_shift) &&
           (this.ma_method == Inputs.ma_method) &&
           (this.applied_price == Inputs.applied_price));
  }  
};

// Variante MT5 do iMACD.
int iMACD2( const string             symbol,
            const ENUM_TIMEFRAMES    period,
            const int                fast_ema_period,
            const int                slow_ema_period,
            const int                signal_period,
            const ENUM_APPLIED_PRICE applied_price )
{
  static HANDLE<MACD> Handles[];  
  const MACD Inputs(symbol, period, fast_ema_period, slow_ema_period, signal_period, applied_price);
  
  return(GetHandle(Handles, Inputs));
}            

// Variante MT5 do iMA.
int iMA2( const string             symbol,
          const ENUM_TIMEFRAMES    period,
          const int                ma_period,
          const int                ma_shift,
          const ENUM_MA_METHOD     ma_method,
          const ENUM_APPLIED_PRICE applied_price )
{
  static HANDLE<MA> Handles[];  
  const MA Inputs(symbol, period, ma_period, ma_shift, ma_method, applied_price);
  
  return(GetHandle(Handles, Inputs));
}            


Em IndicatorsMQL4.mqh, adicione o código acima e faça as seguintes alterações

   int handle=iMACD2(symbol,timeframe,fast_ema_period,slow_ema_period,signal_period,applied_price);
//...
   int handle=iMA2(symbol,timeframe,ma_period,ma_shift,ma_method,applied_price);
 
Rashid Umarov:
Gostaria de uma abordagem desse tipo: retiramos OnCalculate do indicador, modificamos um pouco com um novo nome, adicionamos ao código do indicador e agora podemos usar essa função como uma função de bibilio, passando parâmetros do Expert Advisor para ela. Certo?

Acho que podemos fazer com que o código-fonte de qualquer indicador seja conectado ao Expert Advisor por meio de um enclode. E então trabalhar com eles como se fosse uma função.

Precisamos mexer um pouco com macros e outras peculiaridades. Essa solução não abrangerá todos os indicadores. Mas deve abranger a maioria deles.

 

Tentativa de recuperação:

Estou postando minha versão da medição. Amostra de MACD Um valor de 5 foi tomado como a versão básica do Expert Advisor. Pequenas alterações foram feitas nele. Como todos os valores dos indicadores são coletados em um único local, não foi difícil fazer uma simples substituição de macro: acho que as conclusões são óbvias: ao chamar indicadores no modo MQL4, a velocidade é reduzida em 40%.

Arquivos anexados:
 
Yuriy Koptsev:


veja /results/... aberto - o stop é definido e, em seguida, a rede de arrasto o puxa.


aqui está uma seção do gráfico e o relatório sobre esse local. como ele pode definir um stop de 150 pips para quase todos os lotes com ATR * 0,5 (ATR = 80pp)? com essa configuração, o stop NUNCA deve estar mais longe do que cerca de 40 pips do preço de abertura do lote.... e somente quando ele ficar acima desse nível, ele já estará sendo negociado.
Arquivos anexados:
 
Não tive a chance de lê-lo.
 
Atualizado, man....
 
 
Vasiliy Sokolov:

Tentativa de recuperação:

Estou postando minha versão da medição. Amostra de MACD Um valor de 5 foi tomado como a versão básica do Expert Advisor. Pequenas alterações foram feitas nele. Como todos os valores dos indicadores são coletados em um único local, não foi difícil fazer uma simples substituição de macro: acho que as conclusões são óbvias: ao chamar indicadores no modo MQL4, a velocidade é reduzida em 40%.

Você pode restaurar (editar) sua postagem:

chamar indicadores no modo MQL4, a velocidade é 40% mais lenta.


- O código e a descrição dos resultados da medição foram muito bons.