Si applica una funzione che funziona con il grafico. Per l'indicatore la garanzia della creazione del grafico è il primo inserimento in OnCalculate, per l'Expert Advisor - il primo inserimento in OnTick(). Ma non prima.
Nessun problema. Se non c'è ancora un grafico, fate in modo che la funzione restituisca false e il codice di errore corrispondente. Ma questo non è il caso, la funzione riporta orgogliosamente un'esecuzione riuscita. Si noti che la documentazione non dice che questa è un'indicazione di successo dell'invio del messaggio al grafico. Dice chiaramente: esecuzione di successo della funzione.
Inoltre, questo è un codice per la riproduzione. Infatti, anche prima della chiamata ChartNavigate, ho una chiamata alla serie temporale. E tutti sono riempiti correttamente, come risulta. Cioè, c'è già un grafico, ci sono i suoi dati. Inoltre, è possibile leggere dal grafico gli oggetti grafici che vi sono stati collocati prima della chiusura del terminale.
Quindi, secondo tutte le indicazioni, il grafico esiste già.
Questo è strano. Per me funziona senza problemi.
E un'altra nota: dovete disabilitare il suo offset automatico CHART_AUTOSCROLL prima di compensare il grafico
Nessun problema. Se non c'è ancora un grafico, fate in modo che la funzione restituisca false e il codice di errore corrispondente. Ma questo non è il caso, la funzione riporta orgogliosamente un'esecuzione riuscita. Si noti che la documentazione non dice che questo è un segno di successo dell'invio del messaggio al grafico. Dice chiaramente: esecuzione di successo della funzione.
Inoltre, questo è un codice per la riproduzione. Infatti, anche prima della chiamata ChartNavigate, ho una chiamata alla serie temporale. E tutti sono riempiti correttamente, come risulta. Cioè, c'è già un grafico, ci sono i suoi dati. Inoltre, è possibile leggere dal grafico gli oggetti grafici che vi sono stati collocati prima della chiusura del terminale.
Quindi, secondo tutte le indicazioni, il grafico esiste già.
Grafico e dati sono due grandi differenze.
Tutte le funzioni che si riferiscono ai grafici sono asincrone: cioè a senso unico - sparate e dimenticate. E in questo caso vero significa solo che avete compilato correttamente i campi di questa funzione, niente di più.
Il segno quando tutti i dati sono pronti e i grafici sono tracciati è il primo input di Oncalculate/OnTick.
Un grafico e i dati sono due grandi differenze.
Tutte le funzioni di accesso al grafico sono asincrone: cioè un viaggio a senso unico - sparato e dimenticato. In questo caso, vero significa solo che avete riempito correttamente i campi di questa funzione, niente di più.
Il segno quando tutti i dati sono pronti e i grafici sono tracciati è il primo input per Oncalculate/OnTick.
Allora come si spiega il fatto che per me funziona perfettamente? In OnInit() esattamente come nel primo post del thread... Perché ti inventi delle sciocchezze?
Questo è strano. Per me funziona senza problemi.
Che tipo di costruzione hai? Ho il 1861.
E un'altra nota: dovreste disabilitare il suo offset automatico CHART_AUTOSCROLL prima di compensare il grafico
Sì, l'ho indicato nel primo passo per la riproduzione.
Qual è la tua costruzione? Ho il 1861.
Sì, è quello che ho indicato nel primo passo per il replay.
Ho anche il 1861. Sono riuscito a riprodurlo solo una volta. Tutti gli altri tentativi hanno funzionato bene.
Un grafico e i dati sono due grandi differenze.
Tutte le funzioni di accesso al grafico sono asincrone: cioè un viaggio a senso unico - sparato e dimenticato.
No, non tutti. Quelli che lo fanno sono specificamente commentati. Per esempio, lo stesso ChartApplyTemplate.
In questo caso, vero significa solo che avete riempito correttamente i campi di questa funzione, niente di più.
Come ha fatto la funzione a determinare che l'ID del grafico è corretto, se il grafico stesso non esiste ancora?
Il segno quando tutti i dati sono pronti e i grafici sono tracciati è il primo input per Oncalculate/OnTick.
Sfortunatamente, no. Ecco il codice:
#property indicator_chart_window int OnInit() { Print(__FUNCTION__, ", баров: ", Bars(Symbol(), PERIOD_CURRENT)); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { } 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[]) { Print(__FUNCTION__, ", баров: ", Bars(Symbol(), PERIOD_CURRENT)); return(rates_total); }
Funziona così:
16:01:31.765 Test (XBNUSD,M1) OnInit, баров: 0 16:01:33.531 Test (XBNUSD,M1) OnCalculate, баров: 37026 16:01:34.010 Test (XBNUSD,M1) OnCalculate, баров: 46484
Eseguo l'indicatore su un nuovo simbolo il cui grafico non è ancora stato aperto, cioè non sono ancora stati generati dati su di esso.
Nella prima linea (OnInit) non ci sono effettivamente dati. Tuttavia, c'è l'ID del grafico e possiamo creare oggetti in OnInit() che saranno visualizzati con successo sul grafico.
La seconda linea ha già dei dati, ma è incompleta. I dati sono completi alla terza iterazione.
È ragionevole concludere che la prima chiamata a OnCalculate non è una garanzia di caricamento dei dati. È semplicemente il primo tick sul simbolo dopo l'apertura del grafico, che può arrivare dopo una certa quantità di dati o senza nessun altro dato.
Tornando al problema sollevato nel topic, otteniamo che la funzione ChartNavigate() non controlla la correttezza dei parametri. Se non ci sono ancora dati in OnInit() (0 barre), e il valore -1000 viene passato alla funzione, allora come possiamo considerare questo valore corretto, se non ci sono barre? Dopo tutto, qualsiasi altra funzione restituirebbe un errore quando si accede alla barra con un indice inesistente. Ma qui ha successo. Cos'è esattamente il successo?
Ecco l'indicatore - appositamente messo un ritardo di nove tick, due tipi di movimento grafico e la bandiera di ridisegno forzato (on/off).
//+------------------------------------------------------------------+ //| ProjectName | //| Copyright 2012, CompanyName | //| http://www.companyname.net | //+------------------------------------------------------------------+ #property indicator_chart_window #property indicator_plots 0 //--- input parameters input bool redraw=true; input ENUM_CHART_POSITION position=CHART_BEGIN; //--- long count=0; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int OnInit() { count=0; //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { Comment(""); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ 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[]) { count++; Comment(count); if(count==9) { ResetLastError(); if(position==CHART_BEGIN) { if(ChartNavigate(0,CHART_BEGIN,100)) Print("Успешно. redraw ",redraw,". position ",EnumToString(position)); else Print("Ошибка №",GetLastError(),". redraw ",redraw,". position ",EnumToString(position)); } if(position==CHART_END) { if(ChartNavigate(0,CHART_END,-100)) Print("Успешно. redraw ",redraw,". position ",EnumToString(position)); else Print("Ошибка №",GetLastError(),". redraw ",redraw,". position ",EnumToString(position)); } if(redraw) ChartRedraw(); } return(rates_total); } //+------------------------------------------------------------------+
Preliminare:CHART_BEGIN èstabile.
Ecco l'indicatore - appositamente messo un ritardo di nove tick, due tipi di movimento grafico e la bandiera di ridisegno forzato (on/off)
Preliminare:CHART_BEGIN funziona regolarmente.
Ma cosa succede se non ci sono zecche, è il fine settimana? Poi il timer dovrà essere collegato.
E c'è solo una domanda da risolvere: come determinare se ChartNavigate è stato eseguito con successo? Il fatto che restituisca true, si limita a "ticchettare", non aiuta nel lavoro reale.
![MQL5 - Linguaggio delle strategie di trading integrato nel client terminal MetaTrader 5](https://c.mql5.com/i/registerlandings/logo-2.png)
- App di trading gratuite
- Oltre 8.000 segnali per il copy trading
- Notizie economiche per esplorare i mercati finanziari
Accetti la politica del sito e le condizioni d’uso
Mi sono imbattuto in un problema con la funzione ChartNavigate. Faccio qualcosa di sbagliato o c'è davvero un problema con la funzione. Scrivete se l'avete usato abbastanza spesso.
Ecco il nocciolo del problema: ChartNavigate non sposta il grafico Quando si avvia il terminale se la funzione è chiamata in OnInit(). Ho volutamente letto la documentazione diverse volte. Non c'è scritto da nessuna parte che la funzione non può essere chiamata durante l'inizializzazione.
Codice indicatore per la riproduzione:
Passi per giocare: