pré_calculado - página 6

 
Apenas não apunhalar os ferros nas porcas.
 
Alexey Viktorov:
Isto NÃO está na documentação! Consequentemente, este é um ensaio sobre um tema livre. Assim como minha declaração sobre inicialização automática, ainda mais fria. Pelo menos o meu tinha um termo de responsabilidade.

É impossível descrever absolutamente tudo na documentação.

Se "prev_calculate==0" - significa que temos que passar por todo o buffer de indicadores. Se "prev_calculate!=0", então somente a barra mais à direita ou várias barras novas serão calculadas (usamos limite):

                const int &spread[])
  {
//---
   if(prev_calculated==0)
     {
      Print("prev_calculated==0");
            for(int i=0;i<rates_total;i++)
              {
               //--- здесь принудительно каждому элементу массива присваиваем значение (мне лень писать эти массивы :) )
      
              }
      return(rates_total);
     }
//--- экономный пересчёт только самого правого бара или новых баров
   int limit=rates_total-prev_calculated+1;

//--- а ниже нужно использовать цикл для обсчета самого правого бара или новых баров
   for(int i=0;i<limit;i++)
     {
      ExtBuffer[i]=чевой-то там;
     }
 
Karputov Vladimir:

É impossível descrever absolutamente tudo na documentação.

Se "prev_calculate==0" - significa que temos que passar por todo o buffer de indicadores. Se "prev_calculate!=0", então somente a barra mais à direita ou várias barras novas serão calculadas (usamos limite):

                const int &spread[])
  {
//---
   if(prev_calculated==0)
     {
      Print("prev_calculated==0");
            for(int i=0;i<rates_total;i++)
              {
               //--- здесь принудительно каждому элементу массива присваиваем значение (мне лень писать эти массивы :) )
      
              }
      return(rates_total);
     }
//--- экономный пересчёт только самого правого бара или новых баров
   int limit=rates_total-prev_calculated+1;

//--- а ниже нужно использовать цикл для обсчета самого правого бара или новых баров
   for(int i=0;i<limit;i++)
     {
      ExtBuffer[i]=чевой-то там;
     }




Qual é o valor? Eu não preciso de nenhum valor, exceto a barra mais à direita. MAS!!! Então, quando esta à direita se desloca para a esquerda, estes dados devem ser salvos.

Você não precisa escrever todos os buffers, mas poderia escrever um com meus desejos em mente. Se for a primeira corrida, toda a história deve estar vazia. Se a pré-cálculo foi redefinido como resultado da troca do histórico, TUDO que foi colocado em buffer deve permanecer inalterado. Mesmo que haja buracos.

 
Karputov Vladimir:

Conclusões preliminares:

1. Os indicadores não podem depender da inicialização das matrizes indicadoras no OnInit():

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
...
   ArrayInitialize(balance, 0.0);    // принудительная
   ArrayInitialize(equityMax, 0.0);  // инициализация
   ArrayInitialize(equityMaxB, 0.0); // всех
   ArrayInitialize(equityMin, 0.0);  // буферов
   ArrayInitialize(equityMinB, 0.0); // индикатора

...
//---
   return(INIT_SUCCEEDED);
  }

2. Nos indicadores é obrigatório passar por toda a matriz ou somente elementos alterados na OnCalculate().

De que você está falando bobagem? Se esta inicialização for implementada na OnCalculate, ela será inicializada sem nenhum laço. Mas se for pré-calculado, ele limpa todos os dados que foram acumulados durante o trabalho...
 
Alexey Viktorov:
Por que você está falando bobagens? Se esta inicialização for colocada na OnCalculate, ela é zerada sem nenhum ciclo. Mas se zeramos os dados pré-calculados, isso limpa todos os dados que foram acumulados durante a operação...
Por favor, use expressões. E veja exemplos de indicadores da entrega padrão: Catálogo de dados\MQL5\Indicadores\Exemplos\.
 
Alexey Viktorov:

Qual é o valor??? Não preciso de nenhum valor a não ser a barra mais à direita. MAS!!! Então, quando esta mais à direita se desloca para a esquerda, esses dados precisam ser salvos...

...

Eu já sugeri um caminho:

Fórum sobre comércio, sistemas automatizados de comércio e teste de estratégias comerciais

pré_calculado

Karputov Vladimir, 2016.10.18 15:11

Desculpe pelo atraso na resposta. A única maneira de salvar os valores calculados para um determinado período de tempo é salvá-los em um arquivo. Você precisa cuidar da sincronização - para que ao ler do arquivo os dados sejam colocados em suas barras. A forma mais lógica é sincronizá-la com o tempo de abertura da barra, mas pode haver algumas nuances: por exemplo, o tempo de abertura da barra (salvo em um arquivo) era 2016.09.05. 25:02, mas agora há uma barra no gráfico com tempo igual a 2016.09.05. 25:01.

Um indicador não é um banco de dados ou um repositório.

Portanto, se o indicador exibir dados que depois não podem ser calculados sobre o histórico, então é necessário apenas salvar o buffer do indicador em um arquivo, e depois (em caso de troca de histórico) ler e sincronizar o arquivo e as barras.
 
Karputov Vladimir:

Eu já sugeri um caminho:

Um indicador não é um banco de dados ou um repositório.

Portanto, se o indicador mostrar os dados, que então não podem ser calculados sobre o histórico, então temos apenas que salvar o buffer indicador em um arquivo, e então (no caso de paginação do histórico) realizar a leitura e sincronizar o arquivo e as barras.

Alexey Viktorov:

... e de preferência sem escrever para um arquivo ou ainda mais para a GV.

prev_calculated
prev_calculated
  • www.mql5.com
Форум трейдеров MQL5.community
 

Vladimir, uma vez que você dedicou este tópico especificamente para o pré-cálculo, torne-o útil sobre este tópico. Antes de tudo, deve-se especificar o problema que geralmente ocorre com esta variável. Se você não estiver familiarizado com estes problemas, eu formularei

---

a-- apesar de dizer na ajuda

prev_calculated  // обработано баров на предыдущем вызове

A razão é (está escrito em ajuda + dito pelos desenvolvedores) que a variável é zerada quando o checksum muda, geralmente por causa da troca de histórico.

---

b - você também não pode usar o pré-cálculo == 0 como bandeira da primeira corrida onCalculate. Pela mesma razão

---

c - e você também não pode usar pré_calculo == 0 como bandeira de paging do histórico

---

Para reduzir o desgaste dos usuários, o texto deve ser breve e inequívoco: se a paginação do histórico não tiver acontecido na chamada atual da OnCalculate, o pré-cálculo contém o número de barras processadas na chamada anterior. Se isso aconteceu - é zerada

---

Todos os 3 problemas listados podem ser resolvidos com muletas. Entretanto, como o MT5 não pode ter muletas por definição, Vladimir, você poderia criar uma solução atraente para esses três problemas? Um feio é algo parecido com isto:

#property indicator_chart_window
#property indicator_buffers  0
#property indicator_plots    0


struct BROWNIE {
  int   i_Prew_Calculated;  // кол-во посчитанных баров
  bool  b_First_Run;        // флаг первого запуска
  bool  b_History_Updated;  // флаг обновления истории
  
  BROWNIE() {
    i_Prew_Calculated = WRONG_VALUE;
    b_First_Run = true;
    b_History_Updated = false;
  }
  
  void f_Reset(bool b_Reset_First_Run = true) {
    i_Prew_Calculated = WRONG_VALUE;
    if(b_Reset_First_Run) b_First_Run = true;
    b_History_Updated = false;
  }
  
  void f_Update(int i_New_Prew_Calculated = WRONG_VALUE) {
    if(i_New_Prew_Calculated > -1) {
      b_History_Updated = i_New_Prew_Calculated == 0 && i_Prew_Calculated > WRONG_VALUE;
      if(b_First_Run) b_First_Run = false;
      
      if(i_Prew_Calculated == WRONG_VALUE) i_Prew_Calculated = i_New_Prew_Calculated;
      else if(i_New_Prew_Calculated > 0) i_Prew_Calculated = i_New_Prew_Calculated;
    }
  }
};
BROWNIE go_Brownie;


int OnInit(void) {return(INIT_SUCCEEDED);}


void OnDeinit(const int reason) {
  go_Brownie.f_Reset(reason != REASON_CHARTCHANGE);
}



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 &TickVolume[],
    const long &Volume[],
    const int &Spread[]
) {
  if(go_Brownie.b_First_Run) {/* обработка 1го запуска */}
  if(go_Brownie.b_History_Updated) {/* обработка обновления истории */}
  go_Brownie.f_Update(prev_calculated);
  
  return(rates_total);
}

Isenção de responsabilidade: Código - apenas uma idéia, eu não a experimentei em um gráfico.

No OnDeinit há uma amostra - processamento para o indicador que não usa tampões, não se importa com TF e símbolo, a cada mudança de TF/símbolo não há necessidade de começar do zero. Por exemplo, ele funciona com elementos gráficos existentes, produz informações sobre o status da conta, pedidos, etc.

---

A propósito

Karputov Vladimir:

Se o buffer indicador fosse salvo em um arquivo, e então (em caso de carregamento do histórico) seria necessário ler e sincronizar o arquivo e as barras.

Você não tem que destruir o disco, você pode salvá-lo em um item de tabela
 
Alexey Viktorov:
... e de preferência sem escrever para um arquivo ou ainda mais para um GV.
Será que isso funcionaria para você?
 
Konstantin Gruzdev:
Talvez isto lhe sirva?

Eu não entrei em detalhes, mas isto é resolvido por esta linha de código. Copiar uma matriz em si mesma com um deslocamento de índice.

double arr[5];
ArrayCopy(arr, arr, 0, 1, 4);
// и дальнейшее заполнение 4го индекса массива.
Você pode inverter e copiar a partir do índice zero e colar a partir do primeiro. Em seguida, o índice zero da matriz será preenchido. E isto é uma coisa bem diferente...))