MT4 iMAOnArray e iBandsOnArray efeito do número de elementos nos cálculos - página 2

 
Sergey Efimenko:
O que você quer dizer, o que eu espero? Escrevi acima, que preciso de 300 últimos valores reais (atuais), e não 300 primeiros (iniciais), além disso, que eu acessei um array no offset 299-0, mas recebo dados no offset de "array end" a "array end - 300" valores (no meu caso de 4999 a 4700), ou seja, no offset 299 é um valor, que deveria estar no offset 4999 e similarmente no offset 0 é um valor, que deveria estar no offset 4700. A questão é: qual é a finalidade do cálculo de valores antigos, quando os valores atuais não são calculados?

Se ficasse claro pelo que você escreveu, não haveria dúvidas.

double  iMAOnArray(
   double       array[],          // массив               // С этим понятно...
   int          total,            // количество элементов // Это у тебя 300
   int          ma_period,        // период               // Это ???
   int          ma_shift,         // сдвиг средней        // понятно
   int          ma_method,        // метод усреднения     // понятно
   int          shift             // сдвиг                // А здесь чему равна i???
   );

Foi solicitado que você mostrasse uma amostra de código, mas você mostrou apenas um fragmento de um exemplo. Sobre o resto, você só pode adivinhar que está tudo no laço. Em que valor de mim você quer obter os últimos valores, os atuais? Em i = 4700 ou onde?

 
Alexey Viktorov:

Se estivesse claro pelo que você escreveu, então não haveria dúvidas.

Foi-lhe pedido que mostrasse um exemplo de código e você só mostrou um pedaço de exemplo. Sobre o resto, você só pode adivinhar que tudo está em um loop. Em que valor de mim você quer obter os últimos valores, os atuais? Em i = 4700 ou onde?

Se você usou estas funções com limitação de comprimento da matriz de cálculo na prática, você entenderá o que quero dizer, caso contrário, qual é o objetivo do raciocínio teórico...? E o que não está claro sobre minha peça de código? Eu citei seções absolutamente idênticas com a única diferença de que no primeiro caso eu não uso limitação de comprimento para o cálculo da matriz. Neste caso, não importa em absoluto qual período de cálculo, a média de turno ou o método de cálculo da média, porque são os mesmos em ambos os casos? O valor do turno, como eu escrevi acima, é usado exatamente da mesma forma. Substitua "i" por sua variável de turno no laço, substitua a função GetValue(i) por pelo menos Open[i], faça as três arrays 3 mencionadas exibindo buffers do indicador e veja como a primeira e a segunda funcionam. Entretanto, aqui está um exemplo do código completo da variante simples do indicador em duas variantes para uma melhor compreensão do problema:

//isso funciona bem:
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property  indicator_color1 clrYellow
#property  indicator_color2 clrGreen
#property  indicator_color3 clrRed
double Buffer[],BufferMA[],BufferBMA[]; bool firstrun=true;
int init() { firstrun=true; SetIndexBuffer(0,Buffer); SetIndexBuffer(1,BufferMA); SetIndexBuffer(2,BufferBMA); return(0); }
int start() { int i,limit; int counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; limit=Bars-counted_bars-1;
   if(firstrun) {ArrayInitialize(Buffer,Open[Bars-1]); ArrayInitialize(BufferMA,Open[Bars-1]); ArrayInitialize(BufferBMA,Open[Bars-1]); firstrun=false; }
   for(i=limit; i>=0; i--) { Buffer[i]=Open[i]; BufferMA[i]=iMAOnArray(Buffer,0,12,0,0,i); BufferBMA[i]=iBandsOnArray(Buffer,0,12,2,0,MODE_MAIN,i); }
return(0); }

// não funciona corretamente:

#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property  indicator_color1 clrYellow
#property  indicator_color2 clrGreen
#property  indicator_color3 clrRed
double Buffer[],BufferMA[],BufferBMA[]; bool firstrun=true;
int init() { firstrun=true; SetIndexBuffer(0,Buffer); SetIndexBuffer(1,BufferMA); SetIndexBuffer(2,BufferBMA); return(0); }
int start() { int i,limit; int counted_bars=IndicatorCounted(); if(counted_bars<0) return(-1); if(counted_bars>0) counted_bars--; limit=Bars-counted_bars-1;
   if(firstrun) {ArrayInitialize(Buffer,Open[Bars-1]); ArrayInitialize(BufferMA,Open[Bars-1]); ArrayInitialize(BufferBMA,Open[Bars-1]); firstrun=false; }
   for(i=limit; i>=0; i--) { Buffer[i]=Open[i]; BufferMA[i]=iMAOnArray(Buffer,300,12,0,0,i); BufferBMA[i]=iBandsOnArray(Buffer,300,12,2,0,MODE_MAIN,i);  }
return(0); }

Após desenhar os indicadores no gráfico, ir para o início (à esquerda) do gráfico e olhar para 1 indicador a partir de 12 barras, é o início do preenchimento "não vazio" de 2 e 3 da matriz, lembre-se aproximadamente dos primeiros valores que diferem de 0, depois mova o gráfico para as cotações atuais e olhe valores a partir de 300 barras, assim os valores de 2 (inferior) indicador serão iguais aos que você viu no início do gráfico de 1 indicador, enquanto que na idéia, os valores devem combinar com a corrente. Espero ter explicado isso claramente. Além disso, se você colocar os gráficos em um gráfico on-line, o primeiro funcionará bem e o segundo "pendurará no seu próprio".

 
Sergey Efimenko:


Não apenas o código não é arquivado, mas você insere o código como texto simples. Por favor, insira o código corretamente.
 

Apresentarei seu código de uma forma mais legível e em uma nova notação (na verdade, quanto tempo mais podemos usar este início de int anacrônica() em indicadores????):

Indicador 1:

//+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property  indicator_color1 clrYellow
#property  indicator_color2 clrGreen
#property  indicator_color3 clrRed
double Buffer[];
double BufferMA[];
double BufferBMA[];
bool firstrun=true;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   firstrun=true;
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
   SetIndexBuffer(1,BufferMA,INDICATOR_DATA);
   SetIndexBuffer(2,BufferBMA,INDICATOR_DATA);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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 i,limit;
   limit=rates_total-prev_calculated-1;
   if(prev_calculated==0)
     {
      ArrayInitialize(Buffer,open[rates_total-1]);
      ArrayInitialize(BufferMA,open[rates_total-1]);
      ArrayInitialize(BufferBMA,open[rates_total-1]);
     }
   for(i=limit; i>=0; i--)
     {
      Buffer[i]=open[i];
      BufferMA[i]=iMAOnArray(Buffer,0,12,0,MODE_SMA,i);
      BufferBMA[i]=iBandsOnArray(Buffer,0,12,2,0,MODE_MAIN,i);
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

Indicador 2:

//+------------------------------------------------------------------+
//|                                                         Test.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property  indicator_color1 clrYellow
#property  indicator_color2 clrGreen
#property  indicator_color3 clrRed
double Buffer[];
double BufferMA[];
double BufferBMA[];
bool firstrun=true;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   firstrun=true;
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
   SetIndexBuffer(1,BufferMA,INDICATOR_DATA);
   SetIndexBuffer(2,BufferBMA,INDICATOR_DATA);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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 i,limit;
   limit=rates_total-prev_calculated-1;
   if(prev_calculated==0)
     {
      ArrayInitialize(Buffer,open[rates_total-1]);
      ArrayInitialize(BufferMA,open[rates_total-1]);
      ArrayInitialize(BufferBMA,open[rates_total-1]);
     }
   for(i=limit; i>=0; i--)
     {
      Buffer[i]=open[i];
      BufferMA[i]=iMAOnArray(Buffer,300,12,0,MODE_SMA,i);
      BufferBMA[i]=iBandsOnArray(Buffer,300,12,2,0,MODE_MAIN,i);
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

E o resultado da execução:

Resultado

о

Arquivos anexados:
Test.mq4  3 kb
Test300.mq4  3 kb
 
Sergey Efimenko:

Se você tiver utilizado estas funções

Se não o tivesse feito, eu não estaria fazendo perguntas para sugerir a solução certa.

Para que serve tomar 300 barras se você precisa calcular um período de 12? Mesmo que você precise dele "porque", você deve entender quais seriam os 12 elementos no cálculo da média. E a dica sobre a direção da indexação da matriz foi muito correta.

Para entender, faça experimentos com cálculo manual em papel ou em uma calculadora, ou em Excel.

 

Quando olho para as respostas, percebo que estou apenas perdendo meu tempo aqui, tentando mostrar a essência do problema e obtendo a "beleza" do código em resposta (obrigado, é claro, mas o código proposto foi escrito em dois minutos apenas para mostrar a essência do problema e não requer nenhuma legibilidade ou outras conversões)...

E especialmente encantado com a resposta antes do meu posto. Que calculadora, que cálculos manuais, que indexação? Caros usuários, por favor, entendam a essência da situação para não desperdiçar não apenas seu tempo, mas também o de outra pessoa. Por favor, releia meus posts cuidadosamente, mas se for difícil, responderei brevemente: a direção da indexação da matriz em ambos os casos está correta, o tamanho dos cálculos necessários e outros parâmetros modificáveis, como é mostrado no código primário é definido com variáveis externas, a variante de criar uma função própria foi discutida acima (e na verdade é a única solução correta), mas repito, eu gostaria de obtê-la do MT4 embutido.

Em geral, graças a todos, vou resumir: ou servicedesk ou meus próprios análogos de funções.

 

E estou desanimado com a resposta antes do meu posto.

Se você é tão teimoso, => servicedesk, e eles só respondem a tais perguntas por tédio, e raramente se aborrecem.

Deixe-me tentar novamente...

iMAOnArray() toma, no seu caso, 300 barras e calcula o valor médio das últimas 12 barras em trezentas. Para obter a média das primeiras 12 barras, deve-se inverter a indexação da matriz, ArraySetAsSeries(BufferMA, falso); ou tomar apenas 12 barras.

BufferMA[i]=iMAOnArray(Buffer,12,12,0,MODE_SMA,i);

Assim, ao invés de tentar entender como funciona e como utilizá-lo, você simplesmente afirmou que não funciona ou funciona incorretamente. E não é correto, na sua opinião.

O que há a seguir sobre a beleza do código: Você acha interessante para alguém quebrar os olhos lendo seu código quando está tudo escrito em uma linha? Errado. Eu não o li pessoalmente. Graças ao pequeno baterista por sua paciência várias vezes ao dia para dirigir a todos... para o lugar errado.

 

Eu queria responder muito "em detalhes", mas depois de reler os posts novamente, eu apaguei minha resposta e finalmente percebi que estava apenas perdendo tempo aqui, explicando a mesma coisa várias vezes em palavras diferentes...

PS Todo obrigado e realmente obrigado "Barabashke" (Vladimir), ele se saiu bem, mas toda esta situação não valeu seu trabalho, ficarei ainda mais grato se não for difícil fazer, uma captura de tela em uma chave anterior, adicionando uma terceira opção e mostrando o que aconteceria se você seguisse o conselho de mudar a direção da indexação. Para pôr um fim à questão de como a função funciona.

 
Sergey Efimenko:

Eu queria responder muito "em detalhes", mas depois de reler os posts novamente, eu apaguei minha resposta e finalmente percebi que estava apenas perdendo tempo aqui, explicando a mesma coisa várias vezes em palavras diferentes...

PS Todo obrigado e realmente obrigado "Barabashke" (Vladimir), ele se saiu bem, mas toda esta situação não valeu seu trabalho, ficarei ainda mais grato se não for difícil fazer, uma captura de tela em uma chave anterior, adicionando uma terceira opção e mostrando o que aconteceria se você seguisse o conselho de mudar a direção da indexação. Para pôr um fim à questão de como a função funciona.

Opção 3:

//+------------------------------------------------------------------+
//|                                         Test300AsSeriesFalse.mq4 |
//|                        Copyright 2015, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#property indicator_separate_window
#property indicator_buffers 3
#property  indicator_color1 clrYellow
#property  indicator_color2 clrGreen
#property  indicator_color3 clrRed
double Buffer[];
double BufferMA[];
double BufferBMA[];
bool firstrun=true;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   firstrun=true;
   SetIndexBuffer(0,Buffer,INDICATOR_DATA);
   SetIndexBuffer(1,BufferMA,INDICATOR_DATA);
   SetIndexBuffer(2,BufferBMA,INDICATOR_DATA);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
//---
   ArraySetAsSeries(open,false);
//---
   int i,limit;
   limit=rates_total-prev_calculated-1;
   if(prev_calculated==0)
     {
      ArrayInitialize(Buffer,open[rates_total-1]);
      ArrayInitialize(BufferMA,open[rates_total-1]);
      ArrayInitialize(BufferBMA,open[rates_total-1]);
     }
   for(i=limit; i>=0; i--)
     {
      Buffer[i]=open[i];
      BufferMA[i]=iMAOnArray(Buffer,300,12,0,MODE_SMA,i);
      BufferBMA[i]=iBandsOnArray(Buffer,300,12,2,0,MODE_MAIN,i);
     }
   return(rates_total);
  }
//+------------------------------------------------------------------+

E o resultado geral:

Opções 1, 2 e 3

Arquivos anexados:
 

Não, Vladimir. É um pouco errado.

Neste caso, você deve aplicar o ArraySetAsSeries(array, false); a um array de trezentos elementos entre os quais iMAOnArray() é considerado. Mas é melhor usarmos CopyOpen() em vez do laço de enchimento da matriz.

Segundo entendi, nesta variante será melhor

   for(i=limit; i>=0; i--)
     {
      Buffer[i]=open[i];
      BufferMA[i]=iMAOnArray(Buffer,12,12,0,MODE_SMA,i);
      BufferBMA[i]=iBandsOnArray(Buffer,12,12,2,0,MODE_MAIN,i);
     }
Razão: