다음으로 중요한 검사는 함수가 호출되는 프로그램 유형입니다. 업데이트를 유발하는 지표와 동일한 주기로 시계열 업데이트 요청을 보내는 것은 매우 바람직하지 않다는 점을 기억하십시오. 표시기와 동일한 기호 기간 동안 데이터를 요청하는 것이 바람직하지 않은 것은 표시기가 작동하는 동일한 스레드에서 기록 데이터가 업데이트된다는 사실 때문입니다. 따라서 클린치의 가능성이 높습니다. 확인하기 위해MQL5_PROGRAM_TYPE 수정자 와 함께MQL5InfoInteger() 함수를 사용합니다 .
Прежде чем ценовые данные будут доступны в терминале MetaTrader 5, их необходимо получить и обработать. Для получения данных требуется подключение к торговому серверу MetaTrader 5. Данные поступают с сервера по запросу терминала в виде экономно упакованных блоков минутных баров. Механизм обращения к серверу за данными не зависит от того, каким...
Скайп-чат поддержки продукта: Последние версии библиотек, скриптов и приложений: Сей скрипт продолжение темы закачек котировок обновлением графика. Решил не обновлять старую версию, а выложить заново. Это принципиально новый скрипт. Удалось добиться максимальной надёжности его работы за счёт переноса функций WinAPI в DLL. Скрипт, как и...
예, 이 모든 코드를 알고 있습니다. 이전에 사용했습니다. 몇 년 동안 MQL을 전혀 하지 않았습니다. 올해 지식을 복원하고 있습니다. 개발자가 MT5와 MT4 간에 최대의 호환성을 구현했다는 사실에 매우 놀랐습니다. MQL4의 성능 향상 - 이전에 MT4 프로젝트가 더 이상 개발되지 않을 것이라는 정보가 있었지만 버그만 수정됩니다.
MT4 표시기에서 기록 자동로드에 대한 정보를 찾지 못했기를 바랍니다.
원칙적으로 추가 확인 없이 MT4의 전체 기록을 다운로드하려면 xrenfix 코드를 사용하는 것이 더 쉽습니다. datetime t=0 막대를 .hst 파일에 작성하십시오.
그리고 OnInit에서 요청을 보내고 OnCalculate에서 분석하도록 올바르게 조언되었습니다.
밀리초 타이머는 무엇을 위한 것입니까? 당신은 당신의 행동으로 클라이언트 터미널이 정상적으로 상승하는 것을 방지하고 있습니다. 타이머를 방해하는 것은 Windows 메시지가 아니지만 타이머가 모든 사람을 방해하고 있습니다. 다시 한 번: MT4 클라이언트 터미널의 표시기는 인터페이스 스트림에서 작동합니다.
구현은 정확히 다음과 같습니다. 데이터에 대한 첫 번째 요청은 OnInit()에서 발생합니다. 다음으로 거래 서버와의 연결이 설정되기를 기다리고 OnCalculate()에서! 우리는 이전 TF의 데이터를 얻습니다. 오늘 첫 번째 실행에서 결과를 얻습니다.
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
로그에서 알 수 있듯이 시간과 시간의 잘못된 값이 수신되었습니다.
예, 개발자( @Slava )는 알 수 있습니다. 제가 제공된 모든 조언을 적용하지 않았습니다. 저것들. 처음에는 느린 타이머를 시작 하도록 조언 을 받았지만 여전히 OnInit()에서 빠른 타이머를 시작합니다. 다만, 이 경우에는 고의로 한다. 빠른 타이머가 인터페이스 스레드에서 시작되고 다른 표시기의 데이터 수신을 느리게 할 수 있다면 이는 큰 문제입니다. 문서 어디에도 이에 대한 경고가 없습니다. 시장에 타이머가 자주 있는 프로그램을 쉽게 넣을 수 있습니다. 이 프로그램은 일종의 "바이러스"가 될 수 있고 다른 프로그램의 "파손"으로 이어질 수 있습니다.
위와 관련하여 밀리초 타이머의 동작에 대한 제한을 도입하거나 EventSetMillisecondTimer()에 대한 문서에서 OnInit()에서 함수를 실행할 수 없음을 표시하여 터미널이 상승할 수 있도록 하는 것이 필요하다고 생각합니다 일반적으로 처음에.
오늘 개막일에도 상황은 비슷하며 오류가 반복되었습니다. 테스트 스탠드: 3개의 지표가 있는 하나의 차트. 두 번째는 타이머를 사용하지 않고 세 번째는 타이머를 사용합니다. 모든 사람이 업로드할 때 잘못된 데이터를 받았습니다. 이제 차트에서 타이머를 사용하는 표시기를 제거했습니다. 어떤 일이 일어나는지 지켜보겠습니다.
#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 );
}
//+------------------------------------------------------------------+
그리고 여전히 원하는 결과를 얻지 못합니다. 개발자( @Slava )는 의견을 말하십시오. 여러 이전 TF에서 터미널을 로드할 때 올바른 데이터를 가져오는 것은 불가능합니다. 전제 조건은 터미널을 끈 후 1시간 이상 동안 터미널을 꺼야 한다는 것입니다(시간별 막대 데이터를 가져오기 때문에). 그리고 물론, TF에서의 발사는 1시간 미만입니다.
3. 분석의 흥미로운 순간은 CopyClose()가 반환 하는 것입니다. 요청한 TF에 대한 .hst 파일이 없으면 CopyClose()가 2048 이상을 반환하지 않습니다. 즉, 이것이 다운로드할 수 있는 최대값입니까?
아니요. 2048은 클라이언트에서 사용할 수 없을 때 서버에서 다운로드되는 데이터의 일부입니다.
아니요. 2048은 클라이언트에서 사용할 수 없을 때 서버에서 다운로드되는 데이터의 일부입니다.
흠 오랜만에 MQL을 하고 있는 것 같은데 역시나 의외네요
자, 다음은 도움말의 예입니다. https://www.mql5.com/ru/docs/series/timeseries_access
다음과 같이 명시되어 있습니다.
다음으로 중요한 검사는 함수가 호출되는 프로그램 유형입니다. 업데이트를 유발하는 지표와 동일한 주기로 시계열 업데이트 요청을 보내는 것은 매우 바람직하지 않다는 점을 기억하십시오. 표시기와 동일한 기호 기간 동안 데이터를 요청하는 것이 바람직하지 않은 것은 표시기가 작동하는 동일한 스레드에서 기록 데이터가 업데이트된다는 사실 때문입니다. 따라서 클린치의 가능성이 높습니다. 확인하기 위해 MQL5_PROGRAM_TYPE 수정자 와 함께 MQL5InfoInteger() 함수를 사용합니다 .
저것들. 예제 자체 https://www.mql5.com/ru/code/449
MT4 표시기에서 기록 데이터를 로드하는 데 적합하지 않지만 준비된 .hst 파일이 없는 경우 표시기의 전체 기록을 다운로드하는 방법, 즉 표시기 자체가 기호로 다운로드 기록을 초기화했습니다.
iBars(Symbol(),PERIOD_CURRENT)와 동일한 전체 기록을 "강탈"했는지 어떻게 알 수 있습니까?
iBars()도 잘못된 값을 생성합니까? - 아직 역사 없음, 핵심 iBars() 없음
MT5에서는 히스토리가 문제 없이 흔들리는 것 같고, 히스토리 데이터의 상태를 확인하고 기다리기만 하면 되는데 MT4에서는?
추신: 어제 코드 기반에서 MT4에 대해 올바르게 작동하는 다중 통화 표시기를 찾고 있었지만 코드는 모방의 대상이 아닙니다. 코드 기반의 많은 예에서 표시기에는 단순히 기록 페이징이 없습니다.
4편에서는 "홈키를 꾹 누르고 있다"고 했다. 다른 방법은 없습니다. 오랫동안 주제를 공부했다면 "brick on the keyboard"라는 문구를 기억해야합니다.
https://www.mql5.com/ru/code/9968
https://www.mql5.com/ru/code/9153
https://www.mql5.com/ru/code/9888
내 무료 다운로더를 볼 수 있습니다.
내 무료 다운로더를 볼 수 있습니다.
글쎄, 내가 당신의 코드를 보도록 제안하는 방법은 무엇입니까? 다운로드 내역은 알지만 인디케이터로 다운로드 확인하는 방법을 모르겠습니다
4편에서는 "홈키를 꾹 누르고 있다"고 했다. 다른 방법은 없습니다. 오랫동안 주제를 공부했다면 "brick on the keyboard"라는 문구를 기억해야합니다.
https://www.mql5.com/ru/code/9968
https://www.mql5.com/ru/code/9153
https://www.mql5.com/ru/code/9888
예, 이 모든 코드를 알고 있습니다. 이전에 사용했습니다. 몇 년 동안 MQL을 전혀 하지 않았습니다. 올해 지식을 복원하고 있습니다. 개발자가 MT5와 MT4 간에 최대의 호환성을 구현했다는 사실에 매우 놀랐습니다. MQL4의 성능 향상 - 이전에 MT4 프로젝트가 더 이상 개발되지 않을 것이라는 정보가 있었지만 버그만 수정됩니다.
MT4 표시기에서 기록 자동로드에 대한 정보를 찾지 못했기를 바랍니다.
원칙적으로 추가 확인 없이 MT4의 전체 기록을 다운로드하려면 xrenfix 코드를 사용하는 것이 더 쉽습니다. datetime t=0 막대를 .hst 파일에 작성하십시오.
글쎄, 내가 당신의 코드를 보도록 제안하는 방법은 무엇입니까?
히스토리를 자동으로 불러오기만 하면 되는 줄 알았는데...
유감스럽게도 MT4의 더 높은 시간 프레임에서 데이터를 가져오는 주제로 다시 한 번 돌아가야 합니다. 이번에는 여기에서 제안한 방법이 효과가 없었기 때문입니다.
사용된 코드는 다음과 같습니다.
내가 조언한 대로 데이터 페이징을 구현합니다.
거래, 자동 거래 시스템 및 거래 전략 테스트에 관한 포럼
[SERVICE DESK] 타이머에서 시니어 TF의 시간을 가져오는 동안 오류가 발생했습니다!
슬라바 , 2018.09.27 06:20
그것은 여러 번 논의되었습니다. "오류 4066" 쿼리당 12페이지
그리고 OnInit에서 요청을 보내고 OnCalculate에서 분석하도록 올바르게 조언되었습니다.
밀리초 타이머는 무엇을 위한 것입니까? 당신은 당신의 행동으로 클라이언트 터미널이 정상적으로 상승하는 것을 방지하고 있습니다. 타이머를 방해하는 것은 Windows 메시지가 아니지만 타이머가 모든 사람을 방해하고 있습니다. 다시 한 번: MT4 클라이언트 터미널의 표시기는 인터페이스 스트림에서 작동합니다.
구현은 정확히 다음과 같습니다. 데이터에 대한 첫 번째 요청은 OnInit()에서 발생합니다. 다음으로 거래 서버와의 연결이 설정되기를 기다리고 OnCalculate()에서! 우리는 이전 TF의 데이터를 얻습니다. 오늘 첫 번째 실행에서 결과를 얻습니다.
로그에서 알 수 있듯이 시간과 시간의 잘못된 값이 수신되었습니다.
예, 개발자( @Slava )는 알 수 있습니다. 제가 제공된 모든 조언을 적용하지 않았습니다. 저것들. 처음에는 느린 타이머를 시작 하도록 조언 을 받았지만 여전히 OnInit()에서 빠른 타이머를 시작합니다. 다만, 이 경우에는 고의로 한다. 빠른 타이머가 인터페이스 스레드에서 시작되고 다른 표시기의 데이터 수신을 느리게 할 수 있다면 이는 큰 문제입니다. 문서 어디에도 이에 대한 경고가 없습니다. 시장에 타이머가 자주 있는 프로그램을 쉽게 넣을 수 있습니다. 이 프로그램은 일종의 "바이러스"가 될 수 있고 다른 프로그램의 "파손"으로 이어질 수 있습니다.
위와 관련하여 밀리초 타이머의 동작에 대한 제한을 도입하거나 EventSetMillisecondTimer()에 대한 문서에서 OnInit()에서 함수를 실행할 수 없음을 표시하여 터미널이 상승할 수 있도록 하는 것이 필요하다고 생각합니다 일반적으로 처음에.
그리고 지금 가장 흥미로운. 타이머가 없는 코드:
그리고 여전히 원하는 결과를 얻지 못합니다. 개발자( @Slava )는 의견을 말하십시오. 여러 이전 TF에서 터미널을 로드할 때 올바른 데이터를 가져오는 것은 불가능합니다. 전제 조건은 터미널을 끈 후 1시간 이상 동안 터미널을 꺼야 한다는 것입니다(시간별 막대 데이터를 가져오기 때문에). 그리고 물론, TF에서의 발사는 1시간 미만입니다.
타이머가 작동하지 않았습니다.