prev_calcolato - pagina 6

 
Non c'è bisogno di pestare i ferri con le noci.
 
Alexey Viktorov:
Questo NON è nella documentazione! Di conseguenza, questo è un saggio su un argomento libero. Proprio come la mia affermazione sull'inizializzazione automatica, ancora più figa. Almeno il mio aveva un disclaimer...

È impossibile descrivere assolutamente tutto nella documentazione.

Se "prev_calculate==0" - significa che dobbiamo passare attraverso l'intero buffer dell'indicatore. Se "prev_calculate!=0", allora solo la barra più a destra o diverse nuove saranno calcolate (usiamo il 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:

È impossibile descrivere assolutamente tutto nella documentazione.

Se "prev_calculate==0" - significa che dobbiamo passare attraverso l'intero buffer dell'indicatore. Se "prev_calculate!=0", allora solo la barra più a destra o diverse nuove saranno calcolate (usiamo il 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 è il valore? Non ho bisogno di valori, tranne che per la barra più a destra. MA!!! Poi quando questo più a destra si sposta a sinistra questi dati devono essere salvati...

Non devi scrivere tutti i buffer, ma potresti scriverne uno con i miei desideri in mente. Se è la prima esecuzione, tutta la storia dovrebbe essere vuota. Se prev_calculated è stato resettato come risultato dello swapping della storia, tutto ciò che è stato messo nel buffer dovrebbe rimanere invariato. Anche se ci sono dei buchi.

 
Karputov Vladimir:

Conclusioni preliminari:

1. Gli indicatori non possono fare affidamento sull'inizializzazione degli array di indicatori in 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. Negli indicatori è obbligatorio passare l'intero array o solo gli elementi modificati in OnCalculate().

Di cosa stai parlando senza senso? Se questa inizializzazione è implementata in OnCalculate, sarà inizializzata senza alcun ciclo. Ma se prev_calcola, cancella tutti i dati che sono stati accumulati durante il lavoro...
 
Alexey Viktorov:
Perché dici cose senza senso? Se questa inizializzazione viene messa in OnCalculate, viene azzerata senza alcun ciclo. Ma se azzeriamo prev_calculated, cancella tutti i dati che sono stati accumulati durante l'operazione...
Per favore, usate le espressioni. E guardate gli esempi di indicatori dal set di consegna standard: Catalogo dei dati MQL5, Indicatori, Esempi.
 
Alexey Viktorov:

Qual è il valore? Non ho bisogno di nessun valore oltre alla barra più a destra. MA!!! Poi quando questo più a destra si sposta a sinistra, quei dati devono essere salvati...

...

Ho già suggerito un modo:

Forum sul trading, sistemi di trading automatico e test di strategie di trading

prev_calcolato

Karputov Vladimir, 2016.10.18 15:11

Scusa per il ritardo nella risposta. L'unico modo per salvare i valori calcolati per un dato periodo di tempo è quello di salvarli in un file. È necessario occuparsi della sincronizzazione - in modo che quando si legge dal file i dati siano posizionati sulle loro barre. Il modo più logico è sincronizzarlo con il tempo di apertura della barra, ma ci possono essere alcune sfumature: per esempio, il tempo di apertura della barra (salvato in un file) era 2016.09.05. 25:02, ma ora il grafico ha una barra con tempo uguale a 2016.09.05. 25:01.

Un indicatore non è un database o un archivio.

Pertanto, se l'indicatore visualizza dati che poi non possono essere calcolati sulla storia, allora è solo necessario salvare il buffer dell'indicatore in un file, e poi (in caso di swapping della storia) leggere e sincronizzare il file e le barre.
 
Karputov Vladimir:

Ho già suggerito un modo:

Un indicatore non è un database o un archivio.

Quindi, se l'indicatore mostra i dati, che poi non possono essere calcolati sulla storia, allora dobbiamo solo salvare il buffer dell'indicatore in un file, e poi (nel caso della paginazione della storia) eseguire la lettura e sincronizzare il file e le barre.

Alexey Viktorov:

... e preferibilmente senza scrivere su un file o ancora di più su GV.

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

Vladimir, visto che hai dedicato questo argomento specificamente a prev_calculated, rendilo utile su questo argomento. Prima di tutto, dovreste specificare il problema che di solito si verifica con questa variabile. Se non avete familiarità con questi problemi, formulerò

---

a... anche se nella guida c'è scritto

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

La ragione è (è scritto nell'aiuto + detto dagli sviluppatori) che la variabile viene azzerata quando si cambia il checksum - di solito a causa dello swap della storia.

---

b - non potete nemmeno usare prev_calculated == 0 come flag della prima esecuzione di onCalculate. Per la stessa ragione

---

c - e non potete nemmeno usare prev_calculated == 0 come flag di paginazione della storia

---

Per ridurre l'usura degli utenti, la formulazione dovrebbe essere breve e non ambigua: se la paginazione della storia è fallita sulla chiamata corrente di OnCalculate, allora prev_calculated contiene il numero di barre elaborate sulla chiamata precedente. Se è successo - viene azzerato

---

Tutti e 3 i problemi menzionati possono essere risolti con le stampelle. Tuttavia, dato che MT5 non può avere stampelle per definizione, Vladimir, potresti creare una soluzione interessante per questi tre problemi? Un brutto è qualcosa del genere:

#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);
}

Disclaimer: Codice - solo un'idea, non l'ho provato su un grafico.

In OnDeinit c'è un esempio - elaborazione per l'indicatore, che non usa buffer, non si preoccupa di TF e simbolo, e ad ogni cambio di TF/simbolo non c'è bisogno di ripartire da zero. Per esempio, funziona con elementi grafici esistenti, produce informazioni sullo stato dell'account, ordini, ecc.

---

A proposito

Karputov Vladimir:

Se il buffer dell'indicatore venisse salvato in un file, e poi (in caso di caricamento della storia) sarebbe necessario leggere e sincronizzare il file e le barre.

Non c'è bisogno di distruggere il disco, si può salvare su un elemento del grafico
 
Alexey Viktorov:
... e preferibilmente senza scrivere su un file o ancora di più su un GV.
Andrebbe bene per voi?
 
Konstantin Gruzdev:
Forse questo sarebbe un bene per te?

Non sono entrato nei dettagli, ma questo è risolto da questa linea di codice. Copiare una matrice in se stessa con uno spostamento di indice.

double arr[5];
ArrayCopy(arr, arr, 0, 1, 4);
// и дальнейшее заполнение 4го индекса массива.
Potete invertire e copiare dall'indice zero e incollare dal primo. Poi l'indice zero dell'array sarà riempito. E questa è tutta un'altra cosa...))
Motivazione: