3. punto interessante di analisi, cosa restituisce CopyClose(), l'ho controllato io stesso, se non c'è un file .hst per il TF richiesto, CopyClose() non restituisce mai più di 2048 - cioè questo è il valore massimo che può essere scaricato?
No. 2048 è la porzione di dati che viene scaricata dal server quando non ci sono file sul client.
Il prossimo controllo importante è quello di verificare il tipo di programma da cui viene chiamata la funzione. Ricorda che inviare una richiesta di aggiornamento di una serie temporale con lo stesso periodo dell'indicatore che chiama l'aggiornamento è altamente indesiderabile. L'indesiderabilità di richiedere dati dello stesso periodo di tempo di quello dell'indicatore è determinata dal fatto che l'aggiornamento dei dati storici viene eseguito nello stesso thread in cui lavora l'indicatore. Pertanto, c'è un'alta probabilità di uno scontro. Per controllarlo, usiamo la funzioneMQL5InfoInteger() con il modificatoreMQL5_PROGRAM_TYPE.
non è adatto per caricare i dati della storia nell'indicatore MT4, e come posso scaricare l'intera storia dall'indicatore, se non c'è un file .hst preparato, cioè l'indicatore inizializza il caricamento della storia dal proprio simbolo
come posso sapere che qui ho "scaricato" l'intera storia uguale a iBars(Symbol(),PERIOD_CURRENT);
iBars() restituirà anche un valore errato? - non c'è ancora storia, quindi non c'è iBars()
sembra che in MT5 la storia viene scaricata senza problemi, basta aspettare e controllare lo stato dei dati storici, ma in MT4?
PS: in kodobase ieri stavo cercando un indicatore multicurrency correttamente funzionante per MT4, ma i codici non sono soggetti a imitazione, in molti esempi di kodobase, in generale non c'è paginazione storia nell'indicatore
Прежде чем ценовые данные будут доступны в терминале MetaTrader 5, их необходимо получить и обработать. Для получения данных требуется подключение к торговому серверу MetaTrader 5. Данные поступают с сервера по запросу терминала в виде экономно упакованных блоков минутных баров. Механизм обращения к серверу за данными не зависит от того, каким...
Nei quadrupli, il "tasto home è stato premuto". Non c'è altro modo. Se hai studiato l'argomento per un po', dovresti ricordare la frase "mattone sulla tastiera"
Скайп-чат поддержки продукта: Последние версии библиотек, скриптов и приложений: Сей скрипт продолжение темы закачек котировок обновлением графика. Решил не обновлять старую версию, а выложить заново. Это принципиально новый скрипт. Удалось добиться максимальной надёжности его работы за счёт переноса функций WinAPI в DLL. Скрипт, как и...
Come mi suggerisci di guardare il tuo codice? So come scaricare la cronologia, ma non so come controllare l'indicatore di download.
Slava:
In quadruplice "premere il tasto home". Non c'è altro modo. Se studiate la materia da molto tempo, dovreste ricordare la frase "mattone sulla tastiera"
Quando ho iniziato ad usare MQL negli ultimi anni non ho imparato affatto MQL, da quest'anno sono davvero sorpreso che gli sviluppatori abbiano reso la compatibilità tra MT5 e MT4 il più possibile e migliorato le prestazioni di MQL4 - anche se ci è stato detto prima che MT4 come progetto non sarà più sviluppato, ci sono solo bug da risolvere
e qui era una speranza che non ho trovato informazioni sul caricamento automatico della storia nell'indicatore MT4
Fondamentalmente, se si vuole garantire il download dell'intera storia in MT4 e senza controlli aggiuntivi, allora è più facile usare il codice dfix - scrivere la barra datetime t=0 nel file .hst;
Con mio grande rammarico, devo tornare ancora una volta sull'argomento dell'ottenimento di dati TF senior in MT4. Questa volta a causa del fatto che le tecniche suggerite qui non hanno funzionato.
Ecco il codice che usiamo:
#property strict#property indicator_chart_window//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+//--- Время открытия текущего часа, дня и неделиdatetime _weekOpenTime = 0;
datetime _hourOpenTime = 0;
datetime _dayOpenTime=0;
//--- Вести лог журналаconstbool inpFileLog=true;
//--- Количество секунд в одном днеconstint SEC_PER_DAY=86400;
//--- Флаг работоспособности индикатораbool _isWorking=true;
//--- Флаг соединения с торговым сервером (для таймера, получаем в OnCalculate())bool _isConnected=false;
//+------------------------------------------------------------------+//| Custom indicator initialization function |//+------------------------------------------------------------------+intOnInit()
{
//--- Сбрасываем время открытия текущего часа, дня и недели
_weekOpenTime= 0;
_dayOpenTime = 0;
_hourOpenTime= 0;
//--- Устанавливаем флаг работоспособности
_isWorking=true;
//--- Сбрасываем флаг установки соединения
_isConnected=false;
//--- Запускаем таймерif(!EventSetMillisecondTimer(20))
{
Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": таймер с частотой 20 не установлен!");
//--- Устанавливаем флаг неработоспособности индикатора
_isWorking=false;
}
//--- Запрос данныхSeriesInfoInteger(_Symbol,PERIOD_W1,SERIES_LASTBAR_DATE);
SeriesInfoInteger(_Symbol,PERIOD_D1,SERIES_LASTBAR_DATE);
SeriesInfoInteger(_Symbol,PERIOD_H1,SERIES_LASTBAR_DATE);
//---return( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
//--- Выключаем таймерEventKillTimer();
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+voidOnTimer()
{
//---if(!_isWorking)
return;
//---if(!_isConnected)
return;
//---Print(__FUNCTION__,": Данные старших ТФ загружены!");
//--- Отключаем таймерEventKillTimer();
}
//+------------------------------------------------------------------+//| Custom indicator iteration function |//+------------------------------------------------------------------+intOnCalculate(constint rates_total,
constint prev_calculated,
constdatetime &time[],
constdouble &open[],
constdouble &high[],
constdouble &low[],
constdouble &close[],
constlong &tick_volume[],
constlong &volume[],
constint &spread[])
{
//--- Проверяем связь с серверомif(!IsConnected()) // Если не удалось установить связь с сервером
{
//--- Сбрасываем флаг соединения с сервером
_isConnected=false;
//--- Выходимreturn( 0 );
}
//--- Проверяем первый запуск индикатораif(prev_calculated<=0)
{
//--- Проверяем, записано ли время открытия текущей неделиif(!CheckCurrentWeekOpenTime()) // Если время не записаноreturn(0); // Выходим//--- Проверяем, записано ли время открытия текущего дняif(!CheckCurrentDayOpenTime()) // Если время не записаноreturn(0); // Выходим//--- Проверяем, записано ли время открытия текущего часаif(!CheckCurrentHourOpenTime()) // Если время не записаноreturn(0); // Выходим//--- Устанавливаем флаг соединения с сервером для запуска таймера
_isConnected=true;
}
//---return( rates_total );
}
//+------------------------------------------------------------------+//| Проверяем, записано ли время открытия текущей недели |//+------------------------------------------------------------------+bool CheckCurrentWeekOpenTime()
{
//--- Проверяем, записано ли времяif(_weekOpenTime==0) // Если время не записано
{
//--- Получаем время открытия недельного бараResetLastError();
constdatetime weekBarOpenTime=(datetime)SeriesInfoInteger(_Symbol,PERIOD_W1,SERIES_LASTBAR_DATE);
constint err=GetLastError();
//---if(inpFileLog)
{
Print(__FILE__,": Время открытия недельного бара = "+TimeToString(weekBarOpenTime)+". Ошибка #",err);
}
//--- Проверяем, получено ли время открытия недельного бараif(weekBarOpenTime==0 || err!=0) // Если время бара не получено или история обновляетсяreturn(false); // Возвращаем ложь//--- Запоминаем время открытия текущей недели (время открытия недельного бара - воскресенье)
_weekOpenTime=weekBarOpenTime+SEC_PER_DAY;
//---if(inpFileLog)
{
Print(__FILE__,": Актуальное время открытия текущей недели = "+TimeToString(_weekOpenTime)+". Ошибка #",err);
}
//--- Возвращаем истинуreturn( true );
}
//--- Время открытия недели ранее записано. Возвращаем истинуreturn( true );
}
//+------------------------------------------------------------------+//| Проверяем, записано ли время открытия текущего дня |//+------------------------------------------------------------------+bool CheckCurrentDayOpenTime()
{
//--- Проверяем, записано ли времяif(_dayOpenTime==0) // Если время не записано
{
//--- Получаем время открытия дневного бараResetLastError();
constdatetime tempDayOpenTime=(datetime)SeriesInfoInteger(_Symbol,PERIOD_D1,SERIES_LASTBAR_DATE);
constint err=GetLastError();
//---if(inpFileLog)
{
Print(__FILE__,": Время открытия текущего дня = "+TimeToString(tempDayOpenTime)+". Ошибка #",err);
}
//--- Проверяем, получено ли время открытия дневного бараif(tempDayOpenTime==0 || err!=0) // Если время бара не полученоreturn(false); // Возвращаем ложь//--- Сохраняем в глобальную переменную значение открытия текущего дня
_dayOpenTime=tempDayOpenTime;
//---if(inpFileLog)
{
Print(__FILE__,": Актуальное время открытия текущего дня = "+TimeToString(_dayOpenTime)+". Ошибка #",err);
}
//--- Возвращаем истинуreturn( true );
}
//--- Время открытия дня ранее записано. Возвращаем истинуreturn( true );
}
//+------------------------------------------------------------------+//| Проверяем, записано ли время открытия текущего часа |//+------------------------------------------------------------------+bool CheckCurrentHourOpenTime()
{
//--- Проверяем, записано ли времяif(_hourOpenTime==0) // Если время не записано
{
//--- Получаем время открытия часового бараResetLastError();
constdatetime tempHourOpenTime=(datetime)SeriesInfoInteger(_Symbol,PERIOD_H1,SERIES_LASTBAR_DATE);
constint err=GetLastError();
//---if(inpFileLog)
{
Print(__FILE__,": Время открытия текущего часа = "+TimeToString(tempHourOpenTime)+". Ошибка #",err);
}
//--- Проверяем, получено ли время открытия часового бараif(tempHourOpenTime==0 || err!=0) // Если время бара не полученоreturn(false); // Возвращаем ложь//---
_hourOpenTime=tempHourOpenTime;
//---if(inpFileLog)
{
Print(__FILE__,": Актуальное время открытия текущего часа = "+TimeToString(_hourOpenTime)+". Ошибка #",err);
}
//--- Возвращаем истинуreturn( true );
}
//--- Время открытия часа ранее записано. Возвращаем истинуreturn( true );
}
//+------------------------------------------------------------------+
Implementa il paging dei dati come mi è stato consigliato:
È stato discusso molte volte. 12 pagine su "errore 4066".
Ed è stato correttamente consigliato di inviare la richiesta in OnInit e analizzarla in OnCalculate.
A cosa vi serve un timer al millisecondo? State impedendo al terminale client di avviarsi normalmente. Non sono i messaggi del vento che interferiscono con il tuo timer, è il tuo timer che interferisce con tutti. Ancora una volta: GLI INDICATORI NEL TERMINALE MT4 DEL CLIENTE LAVORANO IN POTENZIALE DI INTERFACCIA.
L'implementazione è esattamente così: la prima richiesta di dati avviene in OnInit(). Poi, aspettiamo che la connessione con il server commerciale sia stabilita, poi in OnCalculate()! otteniamo i dati del TF alto. Otteniamo il risultato al primo lancio di oggi:
2018.10.0409:10:56.266 test_isNewDayInOnCalculate EURGBP.e,M1: OnTimer: Данные старших ТФ загружены!
2018.10.0409:10:56.237 test_isNewDayInOnCalculate EURGBP.e,M1: test_isNewDayInOnCalculate.mq4: Актуальное время открытия текущего часа = 2018.10.0309:00. Ошибка #02018.10.0409:10:56.237 test_isNewDayInOnCalculate EURGBP.e,M1: test_isNewDayInOnCalculate.mq4: Время открытия текущего часа = 2018.10.0309:00. Ошибка #02018.10.0409:10:56.237 test_isNewDayInOnCalculate EURGBP.e,M1: test_isNewDayInOnCalculate.mq4: Актуальное время открытия текущего дня = 2018.10.0300:00. Ошибка #02018.10.0409:10:56.237 test_isNewDayInOnCalculate EURGBP.e,M1: test_isNewDayInOnCalculate.mq4: Время открытия текущего дня = 2018.10.0300:00. Ошибка #02018.10.0409:10:56.237 test_isNewDayInOnCalculate EURGBP.e,M1: test_isNewDayInOnCalculate.mq4: Актуальное время открытия текущей недели = 2018.10.0100:00. Ошибка #02018.10.0409:10:56.237 test_isNewDayInOnCalculate EURGBP.e,M1: test_isNewDayInOnCalculate.mq4: Время открытия недельного бара = 2018.09.3000:00. Ошибка #0
Come possiamo vedere dal log abbiamo ottenuto valori errati di ora e ora del giorno.
Sì, gli sviluppatori(@Slava) possono notare che non ho applicato tutti i consigli che mi sono stati dati. Cioè, eseguo ancora il timer veloce in OnInit(), anche se mi è stato originariamente consigliato di eseguire il timer lento. Tuttavia, in questo caso, è fatto apposta. Se il timer veloce viene avviato nel thread dell'interfaccia e può rallentare il recupero dei dati da altri indicatori - questo è un grosso problema. La documentazione non contiene alcuna avvertenza al riguardo, si può mettere un programma con un timer veloce che può diventare una specie di "virus" e causare "guasti" di altri programmi.
Alla luce di quanto sopra, credo che dovremmo introdurre delle restrizioni sul timer dei millisecondi o specificare nella documentazione di EventSetMillisecondTimer() che la funzione non può essere avviata in OnInit() per permettere al terminale di salire normalmente all'avvio.
Oggi all'apertura della giornata la situazione è simile, l'errore si è ripetuto. Testbed: un grafico, tre indicatori su di esso. Due non usano il timer, il terzo sì. Tutti hanno ricevuto dati errati durante il caricamento. Ora ho rimosso l'indicatore che usa un timer dal grafico e vedrò cosa succede.
#property strict#property indicator_chart_window//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+//--- Время открытия текущего часа, дня и неделиdatetime _weekOpenTime = 0;
datetime _hourOpenTime = 0;
datetime _dayOpenTime=0;
//--- Вести лог журналаconstbool inpFileLog=true;
//--- Количество секунд в одном днеconstint SEC_PER_DAY=86400;
//--- Флаг работоспособности индикатораbool _isWorking=true;
//--- Флаг соединения с торговым сервером (для таймера, получаем в OnCalculate())bool _isConnected=false;
//+------------------------------------------------------------------+//| Custom indicator initialization function |//+------------------------------------------------------------------+intOnInit()
{
//--- Сбрасываем время открытия текущего часа, дня и недели
_weekOpenTime= 0;
_dayOpenTime = 0;
_hourOpenTime= 0;
//--- Устанавливаем флаг работоспособности
_isWorking=true;
//--- Сбрасываем флаг установки соединения
_isConnected=false;
//--- Запрос данныхSeriesInfoInteger(_Symbol,PERIOD_W1,SERIES_LASTBAR_DATE);
SeriesInfoInteger(_Symbol,PERIOD_D1,SERIES_LASTBAR_DATE);
SeriesInfoInteger(_Symbol,PERIOD_H1,SERIES_LASTBAR_DATE);
//---return( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+voidOnDeinit(constint reason)
{
}
//+------------------------------------------------------------------+//| Custom indicator iteration function |//+------------------------------------------------------------------+intOnCalculate(constint rates_total,
constint prev_calculated,
constdatetime &time[],
constdouble &open[],
constdouble &high[],
constdouble &low[],
constdouble &close[],
constlong &tick_volume[],
constlong &volume[],
constint &spread[])
{
//--- Проверяем связь с серверомif(!IsConnected()) // Если не удалось установить связь с сервером
{
//--- Сбрасываем флаг соединения с сервером
_isConnected=false;
//--- Выходимreturn( 0 );
}
//--- Проверяем первый запуск индикатораif(prev_calculated<=0)
{
//--- Проверяем, записано ли время открытия текущей неделиif(!CheckCurrentWeekOpenTime()) // Если время не записаноreturn(0); // Выходим//--- Проверяем, записано ли время открытия текущего дняif(!CheckCurrentDayOpenTime()) // Если время не записаноreturn(0); // Выходим//--- Проверяем, записано ли время открытия текущего часаif(!CheckCurrentHourOpenTime()) // Если время не записаноreturn(0); // Выходим//--- Устанавливаем флаг соединения с сервером для запуска таймера
_isConnected=true;
//---Print(__FUNCTION__,": Данные старших ТФ загружены!");
}
//---return( rates_total );
}
//+------------------------------------------------------------------+//| Проверяем, записано ли время открытия текущей недели |//+------------------------------------------------------------------+bool CheckCurrentWeekOpenTime()
{
//--- Проверяем, записано ли времяif(_weekOpenTime==0) // Если время не записано
{
//--- Получаем время открытия недельного бараResetLastError();
constdatetime weekBarOpenTime=(datetime)SeriesInfoInteger(_Symbol,PERIOD_W1,SERIES_LASTBAR_DATE);
constint err=GetLastError();
//---if(inpFileLog)
{
Print(__FILE__,": Время открытия недельного бара = "+TimeToString(weekBarOpenTime)+". Ошибка #",err);
}
//--- Проверяем, получено ли время открытия недельного бараif(weekBarOpenTime==0 || err!=0) // Если время бара не получено или история обновляетсяreturn(false); // Возвращаем ложь//--- Запоминаем время открытия текущей недели (время открытия недельного бара - воскресенье)
_weekOpenTime=weekBarOpenTime+SEC_PER_DAY;
//---if(inpFileLog)
{
Print(__FILE__,": Актуальное время открытия текущей недели = "+TimeToString(_weekOpenTime)+". Ошибка #",err);
}
//--- Возвращаем истинуreturn( true );
}
//--- Время открытия недели ранее записано. Возвращаем истинуreturn( true );
}
//+------------------------------------------------------------------+//| Проверяем, записано ли время открытия текущего дня |//+------------------------------------------------------------------+bool CheckCurrentDayOpenTime()
{
//--- Проверяем, записано ли времяif(_dayOpenTime==0) // Если время не записано
{
//--- Получаем время открытия дневного бараResetLastError();
constdatetime tempDayOpenTime=(datetime)SeriesInfoInteger(_Symbol,PERIOD_D1,SERIES_LASTBAR_DATE);
constint err=GetLastError();
//---if(inpFileLog)
{
Print(__FILE__,": Время открытия текущего дня = "+TimeToString(tempDayOpenTime)+". Ошибка #",err);
}
//--- Проверяем, получено ли время открытия дневного бараif(tempDayOpenTime==0 || err!=0) // Если время бара не полученоreturn(false); // Возвращаем ложь//--- Сохраняем в глобальную переменную значение открытия текущего дня
_dayOpenTime=tempDayOpenTime;
//---if(inpFileLog)
{
Print(__FILE__,": Актуальное время открытия текущего дня = "+TimeToString(_dayOpenTime)+". Ошибка #",err);
}
//--- Возвращаем истинуreturn( true );
}
//--- Время открытия дня ранее записано. Возвращаем истинуreturn( true );
}
//+------------------------------------------------------------------+//| Проверяем, записано ли время открытия текущего часа |//+------------------------------------------------------------------+bool CheckCurrentHourOpenTime()
{
//--- Проверяем, записано ли времяif(_hourOpenTime==0) // Если время не записано
{
//--- Получаем время открытия часового бараResetLastError();
constdatetime tempHourOpenTime=(datetime)SeriesInfoInteger(_Symbol,PERIOD_H1,SERIES_LASTBAR_DATE);
constint err=GetLastError();
//---if(inpFileLog)
{
Print(__FILE__,": Время открытия текущего часа = "+TimeToString(tempHourOpenTime)+". Ошибка #",err);
}
//--- Проверяем, получено ли время открытия часового бараif(tempHourOpenTime==0 || err!=0) // Если время бара не полученоreturn(false); // Возвращаем ложь//---
_hourOpenTime=tempHourOpenTime;
//---if(inpFileLog)
{
Print(__FILE__,": Актуальное время открытия текущего часа = "+TimeToString(_hourOpenTime)+". Ошибка #",err);
}
//--- Возвращаем истинуreturn( true );
}
//--- Время открытия часа ранее записано. Возвращаем истинуreturn( true );
}
//+------------------------------------------------------------------+
E ancora non puoi ottenere il risultato che vuoi. Gli sviluppatori(@Slava), per favore commentate. È impossibile ottenere dati corretti quando si carica il terminale da diversi TF superiori. Condizione obbligatoria è che il terminale deve essere spento più di un'ora dopo lo spegnimento (perché otteniamo i dati della barra di un'ora). E, naturalmente, avvio su TF in meno di un'ora.
Alexey, stai interrogando i dati dei TF senior nell'Inite. Nessuna connessione ancora, molto probabilmente ha restituito un errore. Prova a fare una richiesta con la prima spunta che arriva.
Non posso controllare, sono al cottage e non ho portato il mio tablet con me.
3. punto interessante di analisi, cosa restituisce CopyClose(), l'ho controllato io stesso, se non c'è un file .hst per il TF richiesto, CopyClose() non restituisce mai più di 2048 - cioè questo è il valore massimo che può essere scaricato?
No. 2048 è la porzione di dati che viene scaricata dal server quando non ci sono file sul client.
No. 2048 è un pezzo di dati che viene scaricato dal server quando non ci sono dati sul client.
Hm, faccio MQL da molto tempo, ma è ancora inaspettato per me
OK, ecco un esempio dall'aiuto:https://www.mql5.com/ru/docs/series/timeseries_access
c'è scritto che:
Il prossimo controllo importante è quello di verificare il tipo di programma da cui viene chiamata la funzione. Ricorda che inviare una richiesta di aggiornamento di una serie temporale con lo stesso periodo dell'indicatore che chiama l'aggiornamento è altamente indesiderabile. L'indesiderabilità di richiedere dati dello stesso periodo di tempo di quello dell'indicatore è determinata dal fatto che l'aggiornamento dei dati storici viene eseguito nello stesso thread in cui lavora l'indicatore. Pertanto, c'è un'alta probabilità di uno scontro. Per controllarlo, usiamo la funzioneMQL5InfoInteger() con il modificatoreMQL5_PROGRAM_TYPE.
cioè l'esempiohttps://www.mql5.com/ru/code/449
non è adatto per caricare i dati della storia nell'indicatore MT4, e come posso scaricare l'intera storia dall'indicatore, se non c'è un file .hst preparato, cioè l'indicatore inizializza il caricamento della storia dal proprio simbolo
come posso sapere che qui ho "scaricato" l'intera storia uguale a iBars(Symbol(),PERIOD_CURRENT);
iBars() restituirà anche un valore errato? - non c'è ancora storia, quindi non c'è iBars()
sembra che in MT5 la storia viene scaricata senza problemi, basta aspettare e controllare lo stato dei dati storici, ma in MT4?
PS: in kodobase ieri stavo cercando un indicatore multicurrency correttamente funzionante per MT4, ma i codici non sono soggetti a imitazione, in molti esempi di kodobase, in generale non c'è paginazione storia nell'indicatore
Nei quadrupli, il "tasto home è stato premuto". Non c'è altro modo. Se hai studiato l'argomento per un po', dovresti ricordare la frase "mattone sulla tastiera"
https://www.mql5.com/ru/code/9968
https://www.mql5.com/ru/code/9153
https://www.mql5.com/ru/code/9888
Puoi controllare il mio downloader gratuito.
Puoi vedere il mio downloader gratuito.
Come mi suggerisci di guardare il tuo codice? So come scaricare la cronologia, ma non so come controllare l'indicatore di download.
In quadruplice "premere il tasto home". Non c'è altro modo. Se studiate la materia da molto tempo, dovreste ricordare la frase "mattone sulla tastiera"
https://www.mql5.com/ru/code/9968
https://www.mql5.com/ru/code/9153
https://www.mql5.com/ru/code/9888
Quando ho iniziato ad usare MQL negli ultimi anni non ho imparato affatto MQL, da quest'anno sono davvero sorpreso che gli sviluppatori abbiano reso la compatibilità tra MT5 e MT4 il più possibile e migliorato le prestazioni di MQL4 - anche se ci è stato detto prima che MT4 come progetto non sarà più sviluppato, ci sono solo bug da risolvere
e qui era una speranza che non ho trovato informazioni sul caricamento automatico della storia nell'indicatore MT4
Fondamentalmente, se si vuole garantire il download dell'intera storia in MT4 e senza controlli aggiuntivi, allora è più facile usare il codice dfix - scrivere la barra datetime t=0 nel file .hst;
Quindi come mi suggerisci di guardare il tuo codice?
Pensavo che bastasse che la storia fosse caricata automaticamente...
Con mio grande rammarico, devo tornare ancora una volta sull'argomento dell'ottenimento di dati TF senior in MT4. Questa volta a causa del fatto che le tecniche suggerite qui non hanno funzionato.
Ecco il codice che usiamo:
Implementa il paging dei dati come mi è stato consigliato:
Forum sul trading, sistemi di trading automatico e test di strategie di trading
[SERVICESDESK] Errore nell'ottenere il tempo del vecchio TF nel timer!
Slava, 2018.09.27 06:20
È stato discusso molte volte. 12 pagine su "errore 4066".
Ed è stato correttamente consigliato di inviare la richiesta in OnInit e analizzarla in OnCalculate.
A cosa vi serve un timer al millisecondo? State impedendo al terminale client di avviarsi normalmente. Non sono i messaggi del vento che interferiscono con il tuo timer, è il tuo timer che interferisce con tutti. Ancora una volta: GLI INDICATORI NEL TERMINALE MT4 DEL CLIENTE LAVORANO IN POTENZIALE DI INTERFACCIA.
L'implementazione è esattamente così: la prima richiesta di dati avviene in OnInit(). Poi, aspettiamo che la connessione con il server commerciale sia stabilita, poi in OnCalculate()! otteniamo i dati del TF alto. Otteniamo il risultato al primo lancio di oggi:
Come possiamo vedere dal log abbiamo ottenuto valori errati di ora e ora del giorno.
Sì, gli sviluppatori(@Slava) possono notare che non ho applicato tutti i consigli che mi sono stati dati. Cioè, eseguo ancora il timer veloce in OnInit(), anche se mi è stato originariamente consigliato di eseguire il timer lento. Tuttavia, in questo caso, è fatto apposta. Se il timer veloce viene avviato nel thread dell'interfaccia e può rallentare il recupero dei dati da altri indicatori - questo è un grosso problema. La documentazione non contiene alcuna avvertenza al riguardo, si può mettere un programma con un timer veloce che può diventare una specie di "virus" e causare "guasti" di altri programmi.
Alla luce di quanto sopra, credo che dovremmo introdurre delle restrizioni sul timer dei millisecondi o specificare nella documentazione di EventSetMillisecondTimer() che la funzione non può essere avviata in OnInit() per permettere al terminale di salire normalmente all'avvio.
Ora la parte divertente. Il codice è senza timer:
E ancora non puoi ottenere il risultato che vuoi. Gli sviluppatori(@Slava), per favore commentate. È impossibile ottenere dati corretti quando si carica il terminale da diversi TF superiori. Condizione obbligatoria è che il terminale deve essere spento più di un'ora dopo lo spegnimento (perché otteniamo i dati della barra di un'ora). E, naturalmente, avvio su TF in meno di un'ora.
Il timer si è rivelato non essere coinvolto.