Mais uma vez. Não diz isso em nenhum lugar. Isso é o primeiro de tudo. Em segundo lugar, por que depois é enganador ao mostrar primeiro um código de erro 4066 e depois não?
Os dados são bombeados em lotes e depois processados pelo terminal, e já que você está trabalhando em um timer, você é pausado. Não vejo isso explicitamente em nenhum lugar, mas muitos programadores que escrevem aplicações MTF geralmente sabem disso e eu já lhes falei sobre isso de uma só vez.
Прежде чем ценовые данные будут доступны в терминале MetaTrader 4, их необходимо получить и обработать. Для получения данных требуется подключение к торговому серверу MetaTrader 4. Данные поступают с сервера по запросу терминала в виде экономно упакованных блоков минутных баров. Механизм обращения к серверу за данными не зависит от того, каким...
Os dados são bombeados em porções e depois processados pelo terminal, e como você está em um timer, você é pausado. Sim, não é mencionado explicitamente em nenhum lugar, mas muitos programadores que escrevem aplicações MTF geralmente sabem sobre isso e eu lhes falei sobre isso imediatamente.
Bem, acima de tudo você já nos deu uma variante de verificação de acessibilidade do histórico. Não é perfeito, mas é simples e óbvio.
Sobre entrar "em uma pausa", onde estão as provas?
Eu o li cuidadosamente (e já o li antes). Estou ciente de que os dados (especialmente os TFs mais antigos) nem sempre estão imediatamente disponíveis. Não há problema. Mas por que então a função SeriesInfoInteger() não retorna nenhum erro!? Aqui está a questão!
Assumindo que o pedido cai em alguma pausa/swap/update/break etc., então deixe-o retornar o código de erro != 0. E não haverá nenhum problema!
Tentarei certamente a sua versão do teste e apresentarei um relatório com os resultados.
Com certeza, irá relatar de volta! Funciona para mim! Mas pode haver todo tipo de armadilhas se não funcionar e vamos pensar no que mais podemos fazer.
#property version"1.00"#property strict#property indicator_chart_window//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+//--- Время открытия текущего часа, дня и неделиdatetime _m15OpenTime=0;
//--- Вести лог журналаconstbool inpFileLog=true;
//--- Количество секунд в одном днеconstint SEC_PER_DAY=86400;
//+------------------------------------------------------------------+//| Custom indicator initialization function |//+------------------------------------------------------------------+intOnInit()
{
//--- Запускаем таймерif(!EventSetMillisecondTimer(20))
{
Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": таймер с частотой 20 ms не установлен!");
return( INIT_FAILED );
}
//--- Сбрасываем время открытия текущего бара м15, часа, дня
_m15OpenTime = 0;
//---return( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+//| 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[])
{
return( rates_total );
}
//+------------------------------------------------------------------+//| Timer function |//+------------------------------------------------------------------+voidOnTimer()
{
//--- Проверяем, записано ли время открытия текущего бара М15if(!CheckCurrentM15OpenTime()) // Если время не записаноreturn; // Выходим // Выходим
}
//+------------------------------------------------------------------+//| Проверяем, записано ли время открытия текущего бара М15 |//+------------------------------------------------------------------+bool CheckCurrentM15OpenTime()
{
//--- Проверяем, записано ли времяif(_m15OpenTime==0) // Если время не записано
{
//---ResetLastError();
iTime(NULL,PERIOD_M15,1);
//---if(GetLastError()==ERR_NO_ERROR)
{
ResetLastError();
//--- Запоминаем время открытия бара
_m15OpenTime=iTime(NULL,PERIOD_M15,0);
//---Print(__FILE__,": Актуальное время открытия бара М15 = "+TimeToString(_m15OpenTime)+". Ошибка #",GetLastError());
//--- Возвращаем истинуreturn( true );
}
elsereturn( false );
}
//--- Время открытия М15 ранее записано. Возвращаем истинуreturn( true );
}
Resultado:
2018.09.2114:25:02.793 Custom indicator test_isNewDayInTimer_iTime() EURGBP.e,M1: removed
2018.09.2114:30:44.120 Custom indicator test_isNewDayInTimer_iTime() EURGBP.e,M1: loaded successfully
2018.09.2114:30:44.149 test_isNewDayInTimer_iTime() EURGBP.e,M1: initialized
2018.09.2114:30:44.262 test_isNewDayInTimer_iTime() EURGBP.e,M1: test_isNewDayInTimer_iTime().mq4: Актуальное время открытия бара М15 = 2018.09.2112:15. Ошибка #0
De acordo com as entradas dos registros. O terminal foi desligado às 14:25. A seguir, ligado às 14h30min. Verificamos o horário do bar M15. Começamos com a TF M1. O indicador (código acima) mostrava o tempo real de abertura 12:15 (hora do terminal, atrasado em 2 horas em relação à minha hora local). O resultado deveria ter sido 12:30! Conclusão - o erro está presente. E este método sugerido por @Ihor Herasko não funciona.
Vitaly Gorbunov: Não deixe de fazer um relatório! Funciona para mim! Mas pode haver todo tipo de armadilhas se não funcionar, vamos pensar no que mais podemos fazer.
Vou assinar. Código:
#property version"1.00"#property strict#property indicator_chart_window//+------------------------------------------------------------------+//| |//+------------------------------------------------------------------+//--- Время открытия текущего часа, дня и неделиdatetime _m15OpenTime=0;
//+------------------------------------------------------------------+//| Custom indicator initialization function |//+------------------------------------------------------------------+intOnInit()
{
//--- Запускаем таймерif(!EventSetMillisecondTimer(20))
{
Print(__FUNCTION__,": ОШИБКА #",GetLastError(),": таймер с частотой 20 ms не установлен!");
return( INIT_FAILED );
}
//--- Сбрасываем время открытия текущего бара м15
_m15OpenTime=0;
//---return( INIT_SUCCEEDED );
}
//+------------------------------------------------------------------+//| 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[])
{
return( rates_total );
}
//+------------------------------------------------------------------+//| Timer function |//+------------------------------------------------------------------+voidOnTimer()
{
//--- Проверяем, записано ли время открытия текущего бара М15if(!CheckCurrentM15OpenTime()) // Если время не записаноreturn; // Выходим
}
//+------------------------------------------------------------------+//| Проверяем, записано ли время открытия текущего бара М15 |//+------------------------------------------------------------------+bool CheckCurrentM15OpenTime()
{
//--- Проверяем, записано ли времяif(_m15OpenTime==0) // Если время не записано
{
//---ResetLastError();
if(iBarShift(Symbol(),PERIOD_M15,TimeCurrent(),true)==-1)
{
Print(__FILE__+": Данные истории по последнему часу отсутствуют! Ошибка #",GetLastError());
return( false );
}
//---if(GetLastError()==ERR_NO_ERROR)
{
ResetLastError();
//--- Запоминаем время открытия бара
_m15OpenTime=iTime(NULL,PERIOD_M15,0);
//---Print(__FILE__,": Актуальное время открытия бара М15 = "+TimeToString(_m15OpenTime)+". Ошибка #",GetLastError());
//--- Возвращаем истинуreturn( true );
}
elsereturn( false );
}
//--- Время открытия недели ранее записано. Возвращаем истинуreturn( true );
}
//+------------------------------------------------------------------+
Resultado:
2018.09.2114:48:46.485 Custom indicator test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: removed
2018.09.2115:01:23.158 Custom indicator test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: loaded successfully
2018.09.2115:01:23.175 test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: initialized
2018.09.2115:01:23.295 test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: test_isNewDayInTimer_iBarShirt().mq4: Актуальное время открытия бара М15 = 2018.09.2112:45. Ошибка #0
Desligou o terminal às 14:48h, religou-o às 15:01h. Deveria ter chegado a hora às 13:00 horas. Eu tenho 12:45. Alguma outra pergunta?
Mudei a TF de M1 para M5 e obtive o resultado correto:
2018.09.2115:01:23.295 test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: test_isNewDayInTimer_iBarShirt().mq4: Актуальное время открытия бара М15 = 2018.09.2112:45. Ошибка #02018.09.2115:05:50.057 test_isNewDayInTimer_iBarShirt() EURGBP.e,M1: uninit reason 32018.09.2115:05:50.058 test_isNewDayInTimer_iBarShirt() EURGBP.e,M5: initialized
2018.09.2115:05:50.094 test_isNewDayInTimer_iBarShirt() EURGBP.e,M5: test_isNewDayInTimer_iBarShirt().mq4: Актуальное время открытия бара М15 = 2018.09.2113:00. Ошибка #0
Acho que consegui! O indicador é iniciado imediatamente com o terminal? Se sim, antes de verificar a conexão com o servidor IsConnected() você tem um timer muito rápido que não tem tempo para sincronizar!
Ou faça isso
if(iBarShift(Symbol(),PERIOD_M15,TimeLocal(),true)==-1)
{
Print(__FILE__+": Данные истории по последнему часу отсутствуют! Ошибка #",GetLastError());
return( false );
}
Mas é preciso levar em conta a diferença entre a hora do servidor e a hora local. Escreva de volta com os resultados!
Mais uma vez. Não diz isso em nenhum lugar. Isso é o primeiro de tudo. Em segundo lugar, por que depois é enganador ao mostrar primeiro um código de erro 4066 e depois não?
Os dados são bombeados em lotes e depois processados pelo terminal, e já que você está trabalhando em um timer, você é pausado. Não vejo isso explicitamente em nenhum lugar, mas muitos programadores que escrevem aplicações MTF geralmente sabem disso e eu já lhes falei sobre isso de uma só vez.
https://docs.mql4.com/ru/series/timeseries_access leia-o com atenção.
Bem, acima de tudo você já nos deu uma variante de verificação de acessibilidade do histórico. Não é perfeito, mas é simples e óbvio.
Se esta variante não funcionar, verifique como a seguir.
Os dados são bombeados em porções e depois processados pelo terminal, e como você está em um timer, você é pausado. Sim, não é mencionado explicitamente em nenhum lugar, mas muitos programadores que escrevem aplicações MTF geralmente sabem sobre isso e eu lhes falei sobre isso imediatamente.
https://docs.mql4.com/ru/series/timeseries_access leia-o com atenção.
Bem, acima de tudo você já nos deu uma variante de verificação de acessibilidade do histórico. Não é perfeito, mas é simples e óbvio.
Sobre entrar "em uma pausa", onde estão as provas?
Eu o li cuidadosamente (e já o li antes). Estou ciente de que os dados (especialmente os TFs mais antigos) nem sempre estão imediatamente disponíveis. Não há problema. Mas por que então a função SeriesInfoInteger() não retorna nenhum erro!? Aqui está a questão!
Assumindo que o pedido cai em alguma pausa/swap/update/break etc., então deixe-o retornar o código de erro != 0. E não haverá nenhum problema!
E, acima, você já deu a opção de verificar a acessibilidade da história. Não é perfeito, mas é simples e direto.
Respondeu acima @Ihor Herasko sobre este ponto.
Já respondeu @Ihor Herasko acima sobre este ponto.
Eu dei minha versão do teste acima. Por que perguntar tanto aos desenvolvedores, mas este ponto já é conhecido há muito tempo!
Tentarei certamente sua versão do teste e relatarei os resultados.
Tentarei certamente a sua versão do teste e apresentarei um relatório com os resultados.
Primeiro uma resposta de @Ihor Herasko. Código para reprodução:
Resultado:
De acordo com as entradas dos registros. O terminal foi desligado às 14:25. A seguir, ligado às 14h30min. Verificamos o horário do bar M15. Começamos com a TF M1. O indicador (código acima) mostrava o tempo real de abertura 12:15 (hora do terminal, atrasado em 2 horas em relação à minha hora local). O resultado deveria ter sido 12:30! Conclusão - o erro está presente. E este método sugerido por @Ihor Herasko não funciona.
Não deixe de fazer um relatório! Funciona para mim! Mas pode haver todo tipo de armadilhas se não funcionar, vamos pensar no que mais podemos fazer.
Vou assinar. Código:
Resultado:
Desligou o terminal às 14:48h, religou-o às 15:01h. Deveria ter chegado a hora às 13:00 horas. Eu tenho 12:45. Alguma outra pergunta?
Mudei a TF de M1 para M5 e obtive o resultado correto:
Acho que consegui! O indicador é iniciado imediatamente com o terminal? Se sim, antes de verificar a conexão com o servidor IsConnected() você tem um timer muito rápido que não tem tempo para sincronizar!
Ou faça isso
Mas é preciso levar em conta a diferença entre a hora do servidor e a hora local. Escreva de volta com os resultados!