Ошибки, баги, вопросы - страница 3028

 
fxsaber:
union с единственным полем - странная штука.

Это тоже самое, что и struct - только нагляднее видно ошибку. Об этом даже в документации написано: "В остальном union ведёт себя как структура"

Связка union\char\char тоже странная, и тоже для наглядности, но можно и так переписать:

union X3 { //(3) Error: 'X2' - struct is too large
        char x31[INT_MAX/2+1];
        int  x32[INT_MAX/8+1];
};
чтобы тоже кому то странным не показалось
 
Andrey Dik:

подумайте ещё раз.

Думать надо вам Андрей. Это в вашем коде тараканы.

Ну, я сегодня так настроен… попробую подтолкнуть в нужном направлении:

Открылся новый бар… iBars() увеличилось на единицу…… Но количество посчитанных баров не изменилось. И не изменится пока не пересчитает этот новый бар…

Дальше что¿¿¿

 
Igor Makanu:

это не должно корректно работать в индикаторах:

если не ошибаюсь, то в справке есть разбор скрипта для подкачки данных по всем ТФ и должно быть предупреждение, что нельзя так запрашивать исторические данные из индикатора по причине того, что индикатор работает асинхронно

да и BarsCalculated() рекомендуют использовать один раз после связывания хэндла


UPD: скрипт для подкачки истории и объяснение, почему это не работает в индикаторах: https://www.mql5.com/ru/docs/series/timeseries_access

вы уверены, что поняли смысл кода?

 
Alexey Viktorov:

Думать надо вам Андрей. Это в вашем коде тараканы.

Ну, я сегодня так настроен… попробую подтолкнуть в нужном направлении:

Открылся новый бар… iBars() увеличилось на единицу…… Но количество посчитанных баров не изменилось. И не изменится пока не пересчитает этот новый бар…

Дальше что¿¿¿

уважаемый. не пишите пожалуйста мне, вы не в теме.

или докажите кодом.

 
Andrey Dik:

вы уверены, что поняли смысл кода?

с большой вероятностью - уверен и понял

Вы хотите из индикатора синхронизировать "старший ТФ" перед вызовом другого индикатора

мой же индикатор работает? - можно в него добавить и BarsCalculated() - но как в примерах индикаторов из поставки, например MACD.mql5


ЗЫ: в КБ много мультитаймфремовых индикаторов, если мне нужно вспомнить, что и как делать, то обычно ищу поиском индикаторы от Mladen Rakic и смотрю у него, стиль написания кода своеобразный (вернее форматирование), но точно работоспособные на все 100

https://www.mql5.com/ru/users/mladen

 
Andrey Dik:

уважаемый. не пишите пожалуйста мне, вы не в теме.

или докажите кодом.

Тады, тьфу на вас…

Разработчики на такие глупости не реагируют, Игорю тоже скоро надоест… И оставайтесь разговаривать сам с собою…

Только надо барабашку попросить перенести ваши излияния в отдельную тему, чтобы не загаживать нужную…

 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Andrey Dik, 2021.05.28 05:16

я делаю проверку синхронизированости данных на запрашиваемом старшем ТФ (М5) и готовность индикатора на нём, если не готово, то выход.

в итоге индикатор работает только 1 раз на открытии бара М1, а не на каждом тике:


//проверка готовности данных и индикатора на другом TF
if (SeriesInfoInteger (Symbol (), tf, SERIES_SYNCHRONIZED))
{
  if (iBars (Symbol (), tf) != BarsCalculated (handleFr)) return 0;
}
else return 0;

//проверка на наличие нового бара
if (rates_total == prev_calculated) return rates_total;

неужели использовать свой кастомный прев кальк придётся? надеюсь, разработчики внемлют моим мольбам.

Не совсем понял ваш код. Что должно происходить после "return 0;" на следующем вызове OnCalculate?
 
Alexey Viktorov:

Игорю тоже скоро надоест…

у меня лишь желание разобраться

в МТ5 много подводных камней с синхронизацией, сейчас вопрос как раз и про это

имхо, если в индикаторе используются построения на каждом баре (линии, а не стрелки)

то достаточно такого цикла для экономного расчета:

for(int i = prev_calculated; i < rates_total; i++)
   {
      Buffer[i] = close[i];
   }

если будет первый вызов, то prev_calculated будет = 0, в последующие вызовы будут пересчитаны новые бары


и если оба индикатора будут написаны правильно, то не нужно ничего синхронизировать дополнительно, все будет работать, останется лишь сравнивать CopyBuffer() с требуемым количеством значений вызываемого индикатора

 
Igor Makanu:

у меня лишь желание разобраться

в МТ5 много подводных камней с синхронизацией, сейчас вопрос как раз и про это

имхо, если в индикаторе используются построения на каждом баре (линии, а не стрелки)

то достаточно такого цикла для экономного расчета:

если будет первый вызов, то prev_calculated будет = 0, в последующие вызовы будут пересчитаны новые бары


и если оба индикатора будут написаны правильно, то не нужно ничего синхронизировать дополнительно, все будет работать, останется лишь сравнивать CopyBuffer() с требуемым количеством значений вызываемого индикатора

И я об этом же. Ладно-бы пытаться синхронизировать перед первым запуском, а так…………

 
Igor Makanu:

у меня лишь желание разобраться

в МТ5 много подводных камней с синхронизацией, сейчас вопрос как раз и про это

имхо, если в индикаторе используются построения на каждом баре (линии, а не стрелки)

то достаточно такого цикла для экономного расчета:

если будет первый вызов, то prev_calculated будет = 0, в последующие вызовы будут пересчитаны новые бары


и если оба индикатора будут написаны правильно, то не нужно ничего синхронизировать дополнительно, все будет работать, останется лишь сравнивать CopyBuffer() с требуемым количеством значений вызываемого индикатора

если есть желание разобраться, а не оппонировать, то Вам следовало бы написать что то вроде ниже показанного кода:

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1

#property indicator_label1  "I"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

double         IBuffer[];

int OnInit()
{
   SetIndexBuffer   (0,IBuffer,INDICATOR_DATA);
   ArraySetAsSeries (IBuffer, true);

   return(INIT_SUCCEEDED);
}

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[])
{
   if (rates_total == prev_calculated) return rates_total;
   
   ulong t = GetMicrosecondCount ();
   
   ArraySetAsSeries (high,        true);

   int limit = rates_total - prev_calculated - 1;

   for (int i = limit; i >= 0; i--)
   {
      IBuffer [i] = high [i];
   }

   //----------------------------------------------------------------
   double e = (GetMicrosecondCount () - t) / 1000000.0;
   Print (DoubleToString (e, 6), " sec, рассчитано ", rates_total - prev_calculated, " баров, всего баров ", rates_total);
   return(rates_total);
}
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1

//--- plot I
#property indicator_label1  "I"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrRed
#property indicator_style1  STYLE_SOLID
#property indicator_width1  1

input ENUM_TIMEFRAMES  OldTF = PERIOD_M5;

double IBuffer[];
int    Handle = 0;

int OnInit()
{
   SetIndexBuffer   (0,IBuffer,INDICATOR_DATA);
   ArraySetAsSeries (IBuffer, true);

   Handle = iCustom (Symbol (), OldTF, "OldTF.ex5");
   if (Handle == INVALID_HANDLE)
   {
      Print ("Не удалось получить хендл индикатора OldTF.ex5");
      return INIT_FAILED;
   }

   return INIT_SUCCEEDED;
}

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[])
{
   if (rates_total == prev_calculated) return rates_total;

   if (SeriesInfoInteger (Symbol (), OldTF, SERIES_SYNCHRONIZED))
   {
      if (iBars (Symbol (), OldTF) != BarsCalculated (Handle))
      {
        Print ("Индикатор на периоде ", OldTF, " ещё не рассчитан");
        return 0;
      }
   }
   else 
   {
     Print ("Период ", OldTF, " не синхронизирован.");
     return 0;
   }

   ulong t = GetMicrosecondCount ();

   ArraySetAsSeries (high, true);
   ArraySetAsSeries (time, true);

   int limit = rates_total - prev_calculated - 1;

   double buff [];
   int ind = 0;
   for (int i = limit; i >= 0; i--)
   {
      ind = iBarShift (Symbol (), OldTF, time [i], false);
      if (CopyBuffer (Handle, 0, ind, 1, buff) != -1)
      {
        IBuffer [i] = buff [0];
      }
      else
      {
        Print ("Ошибка копирования буфера ", GetLastError ());
        return 0;
      }
   }

   //----------------------------------------------------------------
   double e = (GetMicrosecondCount () - t) / 1000000.0;
   Print (DoubleToString (e, 6), " sec, расcчитано ", rates_total - prev_calculated, " баров, всего баров ", rates_total);
   return(rates_total);
}

скомпилируйте оба кода и запустите второй. получите что то вроде этого в логах при запуске на М1 и М3 старшего индикатора:

2021.05.28 19:05:01.408 OldTF (EURUSD,M3) 0.000234 sec, расcчитано 50000 баров, всего баров 50000

2021.05.28 19:05:03.860 LitTF (EURUSD,M1) 0.007452 sec, расcчитано 50023 баров, всего баров 50023

2021.05.28 19:06:00.670 OldTF (EURUSD,M3) 0.000001 sec, расcчитано 1 баров, всего баров 50001

2021.05.28 19:06:02.211 LitTF (EURUSD,M1) 0.008180 sec, расcчитано 50024 баров, всего баров 50024

2021.05.28 19:07:00.780 LitTF (EURUSD,M1) 0.000004 sec, расcчитано 1 баров, всего баров 50025

2021.05.28 19:08:01.246 LitTF (EURUSD,M1) 0.000014 sec, расcчитано 1 баров, всего баров 50026

2021.05.28 19:09:00.959 OldTF (EURUSD,M3) 0.000000 sec, расcчитано 1 баров, всего баров 50002

2021.05.28 19:09:01.775 LitTF (EURUSD,M1) 0.006898 sec, расcчитано 50027 баров, всего баров 50027

2021.05.28 19:10:00.830 LitTF (EURUSD,M1) 0.000004 sec, расcчитано 1 баров, всего баров 50028

даже невооружённым взглядом можете заметить во первых, наискорейший из возможных вариантов построения быстрых индикаторов, во вторых, что прев кальк таки обнуляется тогда,

когда его не просят и это приведёт к значительному необоснованному снижению производительности при оптимизации. в данном примере индикатор вынужден полностью пересчитаться на кадом новом баре М3. если не делать синхронизацию, то будете получать дыры при построении индикатора. 

Alexey Viktorov:

Тады, тьфу на вас…

Разработчики на такие глупости не реагируют, Игорю тоже скоро надоест… И оставайтесь разговаривать сам с собою…

Только надо барабашку попросить перенести ваши излияния в отдельную тему, чтобы не загаживать нужную…

посмотрите код выше, съешьте свой паспорт, посыпьте голову пеплом и засуньте свою спесь себе туда, где её никому не будет видно.

Причина обращения: