Прежде чем ценовые данные будут доступны в терминале MetaTrader 5, их необходимо получить и обработать. Для получения данных требуется подключение к торговому серверу MetaTrader 5. Данные поступают с сервера по запросу терминала в виде экономно упакованных блоков минутных баров. Механизм обращения к серверу за данными не зависит от того, каким...
Скайп-чат поддержки продукта: Последние версии библиотек, скриптов и приложений: Сей скрипт продолжение темы закачек котировок обновлением графика. Решил не обновлять старую версию, а выложить заново. Это принципиально новый скрипт. Удалось добиться максимальной надёжности его работы за счёт переноса функций WinAPI в DLL. Скрипт, как и...
#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 );
}
//+------------------------------------------------------------------+
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
#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 );
}
//+------------------------------------------------------------------+
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中呢?
PS:昨天我在kodobase寻找一个正确工作的MT4多币种指标,但代码不受模仿,在kodobase的许多例子中,一般情况下,指标中没有历史分页。
在四胞胎中,"Home键被按下"。没有其他办法。如果你已经研究了一段时间的主题,你应该记得 "键盘上的砖头 "这句话
https://www.mql5.com/ru/code/9968
https://www.mql5.com/ru/code/9153
https://www.mql5.com/ru/code/9888
你可以查看我的免费 下载器。
你可以看到我的免费 下载器。
你建议我怎么看你的代码? 我知道如何下载历史,但我不知道如何检查下载指标。
在四合院 "按主页键"。没有其他办法。如果你已经研究了很久,你应该记得 "键盘上的砖头 "这句话
https://www.mql5.com/ru/code/9968
https://www.mql5.com/ru/code/9153
https://www.mql5.com/ru/code/9888
在过去的几年里,当我开始使用MQL时,我根本没有学习MQL,从今年开始,我真的很惊讶,开发人员尽可能地使MT5和MT4兼容,并提高了MQL4的性能--尽管我们之前被告知,MT4作为一个项目将不再开发,只有错误需要修复。
我希望在MT4指标中找不到关于自动加载历史记录的信息。
基本上,如果你想保证在MT4中下载整个历史记录,并且不需要额外的检查,那么使用dfix代码更容易 - 在.hst文件中写入bar datetime t=0。
那么你建议我如何看待你的代码?
我以为你只需要自动加载历史记录......。
非常遗憾,我不得不再次回到在MT4中获取高级TF数据的话题。这一次是由于这里建议的技术没有发挥作用。
下面是我们使用的代码。
它按照我的建议实现了分页数据。
关于交易、自动交易系统和交易策略测试的论坛
[SERVICESDESK]在计时器中获取旧TF的时间时出错了!
斯拉瓦, 2018.09.27 06:20
这个问题已经讨论过很多次了。12页关于 "错误4066"。
你被建议在OnInit中发送请求,在OnCalculate中分析它是正确的。
你需要一个毫秒级的计时器做什么?你正在阻止客户终端的正常启动。不是风的信息干扰了你的定时器,而是你的定时器干扰了所有人。再次强调:客户的MT4终端中的指示器是以界面潜力来工作的。
实现方式完全是这样的:第一次数据请求发生在OnInit()。然后,我们等待与交易服务器建立连接,然后在OnCalculate()中!我们获得高TF的数据。我们在今天的第一次发布会上得到了结果。
我们可以从日志中看到,我们得到了错误的小时和日间时间的数值。
是的,开发者(@Slava)可能会注意到,我没有应用所有给我的建议。也就是说,我仍然在OnInit()中运行快速定时器,尽管最初有人建议 我运行慢速定时器。然而,在这种情况下,它是故意的。如果快速计时器是在接口线程中启动的,并且会减慢其他指标的数据检索速度--这是一个大麻烦。文档中没有任何关于它的警告,你可以把一个带有快速计时器的程序变成一种 "病毒",导致其他程序的 "崩溃"。
鉴于上述情况,我认为要么我们应该对毫秒计时器引入限制,要么在EventSetMillisecondTimer()的文档中规定该函数不能在OnInit()中启动,以允许终端在启动时正常上升。
现在是有趣的部分。该代码没有任何定时器。
而你仍然无法得到你想要的结果。开发者(@Slava),请评论。当从几个较高的TF中加载终端时,不可能得到正确的数据。义务条件是,终端必须在关机后一小时以上(因为我们得到的是一小时的条形数据)。当然,在TF上启动不到一个小时。
计时器原来没有参与。