Perguntas de Iniciantes MQL5 MT5 MetaTrader 5 - página 1164

 
Roman:

É necessário pensar antecipadamente como o código é executado ao nível da memória, inicialização e retorno do valor.

Não é preciso pensar bem, existem manuais para estas coisas, e nunca houve um manual para alocação de memória em MQL, apenas mensagens de programadores, e muitas vezes com um esclarecimento de que a implementação pode mudar

Ok, a discussão resume-se a quem lê que livro de programação, tenho-o lido desde o liceu e continuo a lê-lo nos últimos 30 anos.

 
Igor Makanu:

Não é preciso pensar bem, existem manuais para estas coisas, e nunca houve um manual para alocação de memória em MQL, apenas mensagens de programadores, e muitas vezes com um esclarecimento de que a implementação pode mudar

Ok, a discussão resume-se a quem lê que livro de programação, tenho-o lido desde o liceu e continuo a lê-lo nos últimos 30 anos

Claro que não precisa de pensar bem, porque deveria... O compilador fará tudo por si só. ))
C# não é C

E vejam o vídeo em __inline.
Explica aí como funcionam as funções em memória daqueles que não fazem qualquer diferença.

 
Vladimir Karputov:

Desenhar primeiro uma imagem e especificar qual é a 'barra zero' para um indicador com o parâmetro de deslocamento.

Desenhado. A barra de zero é realçada com uma linha vertical.


 
RickD:

Desenhado. A barra de zero é realçada com uma linha vertical.


Exemplo de código:

//+------------------------------------------------------------------+
//|                                        iMA Values on a Chart.mq5 |
//|                              Copyright © 2019, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2019, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
//--- input parameters
input int                  Inp_MA_ma_period     = 12;          // MA: averaging period
input int                  Inp_MA_ma_shift      = 5;           // MA: horizontal shift
input ENUM_MA_METHOD       Inp_MA_ma_method     = MODE_SMA;    // MA: smoothing type
input ENUM_APPLIED_PRICE   Inp_MA_applied_price = PRICE_CLOSE; // MA: type of price
//---
int    handle_iMA;                           // variable for storing the handle of the iMA indicator
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create handle of the indicator iMA
   handle_iMA=iMA(Symbol(),Period(),Inp_MA_ma_period,Inp_MA_ma_shift,
                  Inp_MA_ma_method,Inp_MA_applied_price);
//--- if the handle is not created
   if(handle_iMA==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double array_ma[];
   ArraySetAsSeries(array_ma,true);
   int start_pos=0,count=3;
   if(!iGetArray(handle_iMA,0,start_pos,count,array_ma))
      return;

   string text="";
   for(int i=0; i<count; i++)
      text=text+IntegerToString(i)+": "+DoubleToString(array_ma[i],Digits()+1)+"\n";

   Comment(text);
  }
//+------------------------------------------------------------------+
//| Get value of buffers                                             |
//+------------------------------------------------------------------+
bool iGetArray(const int handle,const int buffer,const int start_pos,
               const int count,double &arr_buffer[])
  {
   bool result=true;
   if(!ArrayIsDynamic(arr_buffer))
     {
      PrintFormat("ERROR! EA: %s, FUNCTION: %s, this a no dynamic array!",__FILE__,__FUNCTION__);
      return(false);
     }
   ArrayFree(arr_buffer);
//--- reset error code
   ResetLastError();
//--- fill a part of the iBands array with values from the indicator buffer
   int copied=CopyBuffer(handle,buffer,start_pos,count,arr_buffer);
   if(copied!=count)
     {
      //--- if the copying fails, tell the error code
      PrintFormat("ERROR! EA: %s, FUNCTION: %s, amount to copy: %d, copied: %d, error code %d",
                  __FILE__,__FUNCTION__,count,copied,GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(false);
     }
   return(result);
  }
//+------------------------------------------------------------------+

Resultado:


Como se pode ver, é copiável sem qualquer remendo.

Arquivos anexados:
 
Vladimir Karputov:

Exemplo de código:

Resultado:


Como se pode ver é facilmente copiado, sem qualquer pandeiro.

Exemplo de código. Com base num indicador. O indicador está ocupado a alocar memória tampão.

#property copyright "Copyright 2019"
#property link      ""
#property version   "1.00"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   0

//---

input int                  MA_period = 12;
input int                  MA_shift = 5;
input ENUM_MA_METHOD       MA_method = MODE_SMA;
input ENUM_APPLIED_PRICE   MA_applied_price = PRICE_CLOSE;

int start_pos = 0;

//---

double MA_Calc_Buf[];

int hMA = INVALID_HANDLE;


int OnInit()
{
  SetIndexBuffer(0, MA_Calc_Buf, INDICATOR_CALCULATIONS); 
  ArraySetAsSeries(MA_Calc_Buf, true);
 
  hMA = iMA(NULL, 0, MA_period, MA_shift, MA_method, MA_applied_price);   
  if (hMA == INVALID_HANDLE)
  {
    int LErr = GetLastError();
    PrintFormat("iMA create failed (%d)", LErr);
    return (INIT_FAILED);
  }
 
  return (INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
  if (hMA != INVALID_HANDLE)
  {
    IndicatorRelease(hMA);
    hMA = INVALID_HANDLE;
  }
}

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{ 
  int copied;
  copied = CopyBuffer(hMA, 0, start_pos, rates_total, MA_Calc_Buf);
  if (copied == -1)
  {
    int LErr = GetLastError();
    PrintFormat("CopyBuffer(hMA) failed (%d)", LErr);
    return (prev_calculated);
  }
 
  if (copied == 0)
  {
    PrintFormat("CopyBuffer(hMA) copied 0 bars");
    return (prev_calculated);
  } 
 
  string text = "";
  for (int i=0; i<15; i++)
    text = text + IntegerToString(i) + ": " + DoubleToString(MA_Calc_Buf[i], Digits()+1) + "\n";
 
  Comment(text);

  return (rates_total);
}

Quando start_pos = 0, o valor correspondente à 0ª barra do gráfico está na posição 5. 1.017041 Está na posição 0 no seu EA. Ok.


Mas eu preciso de obter este valor na posição zero.

Eu configuro start_pos = 5. Não obtive o resultado pretendido. O valor que estou à procura está novamente na posição 5.


Eu defino start_pos = -5. Não obtenho o resultado desejado. Mais uma vez, o valor que procuro está na posição 5.


Eu defino start_pos = -10. E só agora obtive o resultado desejado.


 
RickD:

Exemplo de código. Com base no indicador. O indicador está ocupado a alocar memória tampão.

Quando start_pos = 0, o valor correspondente à 0ª barra do gráfico que vemos na posição 5. 1.017041 Na sua EA está na posição 0. Ok.


Mas eu preciso de obter este valor na posição zero.

Eu configuro start_pos = 5. Não obtenho o resultado desejado. O valor que estou à procura está novamente na posição 5.


Eu defino start_pos = -5. Não obtenho o resultado desejado. Mais uma vez, o valor que procuro está na posição 5.


Eu defino start_pos = -10. E só agora obtive o resultado desejado.


Precisamos de compreender a diferença entre o trabalho do Consultor Especialista e o do indicador. Para trabalhos a partir de indicadores, utilizar o exemplo da ajuda(iMA).

Документация по MQL5: Технические индикаторы / iMA
Документация по MQL5: Технические индикаторы / iMA
  • www.mql5.com
//|                                                     Demo_iMA.mq5 | //|                        Copyright 2011, MetaQuotes Software Corp. | //|                                             https://www.mql5.com | //| Перечисление способов создания хэндла                            |  Creation             type=Call_iMA;                ...
 
Vladimir Karputov:

É preciso compreender a diferença entre operar a partir de um EA e a partir de um indicador. Para trabalhar a partir de um indicador, utilizar o exemplo da ajuda(iMA).

Assim, pegue num exemplo da ajuda do iMA, acrescente

   ArraySetAsSeries(iMABuffer, true);
   comm = (string)DoubleToString(iMABuffer[0], Digits());
   ArraySetAsSeries(iMABuffer, false);

   Comment(comm);   

e verificar se o valor é diferente do valor de saída da sua EA, exactamente por ma_shift de barras.

Eu, por outro lado, necessito de obter no indicador no iMABuffer[0] o valor como tem no seu Expert Advisor em array_ma[0].

Pelo menos no momento podemos ver que o comportamento do CopyBuffer para Consultores Especialistas e indicadores é diferente. Se compreender a diferença em CopyBuffer ao trabalhar com um EA e um indicador, por favor especifique a secção apropriada da documentação a estudar.

 

Vou tentar simplificar a questão. Como obter estes valores de MA (a partir da linha vertical vermelha e para a esquerda) para o tampão no indicador? Pode escrever um exemplo?


 
RickD:

Vou tentar simplificar a questão. Como obter estes valores de MA (a partir da linha vertical vermelha e para a esquerda) para o tampão no indicador? Pode escrever um exemplo?


Na imagem do ecrã, a visualização do buffer é deslocada cinco barras para a direita. Então - para obter a quinta barra do tampão indicador (índice 4), e mais à esquerda na lista, de onde devemos obtê-los? De Buffer[4] e mais para a esquerda.

Em teoria. Na prática - não abri o código indicador nem trabalhei com ele durante muito tempo - quase um ano... Experimente.

 
Artyom Trishkin:


Em teoria. Na prática - não abri o código indicador nem trabalhei com ele durante muito tempo - quase um ano... Experimente.

Não se pode perder uma habilidade.

Razão: