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):
constint &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]=чевой-то там; }
È 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):
constint &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.
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.
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...
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.
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.
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:
struct BROWNIE { int i_Prew_Calculated; // кол-во посчитанных баров bool b_First_Run; // флаг первого запуска bool b_History_Updated; // флаг обновления истории
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
Consenti l'uso dei cookie per accedere al sito MQL5.com.
Abilita le impostazioni necessarie nel browser, altrimenti non sarà possibile accedere.
Hai effettuato l'accesso. L'autenticazione a due fattori è stata disattivata. Configurala di nuovo e scansiona un nuovo codice QR, oppure continua con l'autenticazione a due fattori disattivata.
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):
{
//---
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]=чевой-то там;
}
È 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):
{
//---
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.
Conclusioni preliminari:
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...
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.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.... e preferibilmente senza scrivere su un file o ancora di più su GV.
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
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_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
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.
... e preferibilmente senza scrivere su un file o ancora di più su un GV.
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.
ArrayCopy(arr, arr, 0, 1, 4);
// и дальнейшее заполнение 4го индекса массива.