Errors, bugs, questions - page 3028

 
fxsaber:
A union with a single field is a strange thing.

This is the same as struct - only the error is more obvious. It is even written in documentation about it:"Otherwise union behaves as structure".

Union\char\char is also strange, and also for clarity, but it can be rewritten:

union X3 { //(3) Error: 'X2' - struct is too large
        char x31[INT_MAX/2+1];
        int  x32[INT_MAX/8+1];
};
So it doesn't seem strange to anyone, either.
 
Andrey Dik:

think again.

You need to think, Andrei. It's in your code that the cockroaches are there.

Well, I'm so inclined today... I'll try to push in the right direction:

A new bar has opened... iBars() has increased by one...... But the number of bars counted has not changed. And it won't change until it recalculates this new bar...

What's next?

 
Igor Makanu:

this should not work correctly in indicators:

if I'm not mistaken, in the help there is a breakdown of the script for paging data for all TFs and there should be a warning that historical data cannot be requested from the indicator in this way, because the indicator works asynchronously

and it is recommended to use BarsCalculated() once after you bind the handle


UPD: script for history paging and explanation why it doesn't work in indicators:https://www.mql5.com/ru/docs/series/timeseries_access

are you sure you understand the meaning of the code?

 
Alexey Viktorov:

You need to think, Andrei. It's in your code that there are cockroaches.

Well, I'm so inclined today... I'll try to push in the right direction:

A new bar opened... iBars() increased by one...... But the number of bars counted has not changed. And it won't change until it recalculates this new bar...

What's next?

my good man, please don't write to me, you are not in the loop.

Or prove it with code.

 
Andrey Dik:

are you sure you understand the meaning of the code?

With a high probability - sure and understood

You want the indicator to synchronize the "higher TF" before calling another indicator

my indicator works, right? - you can add BarsCalculated() to it - but as in the examples of indicators from the delivery, for example MACD.mql5


HH: there are a lot of multitimeframe indicators in QB. If I need to remember what to do and how to do it, I usually search for indicators by Mladen Rakic and look through his, the style of coding is peculiar (more correctly the formatting), but they are 100% functional

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

 
Andrey Dik:

Dear. please don't write to me, you're not in the loop.

Or prove it with a code.

Well then, phew on you...

Developers do not respond to such nonsense, Igor will get bored soon... And stay and talk to yourself...

Just ask Drummer to move your outpourings into a separate thread ... to avoid cluttering the proper one...

 

Forum on trading, automated trading systems and trading strategy testing

Bugs, bugs, questions

Andrey Dik, 2021.05.28 05:16

I'm trying to check the data synchronization on the requested timeframe (M5) and the readiness of the indicator on it, if it's not ready, i will exit.

As a result, the indicator works only once at M1 bar open, and not at every tick:


//проверка готовности данных и индикатора на другом 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;

I hope the developers will listen to my pleas.

I don't quite understand your code. What should happen after "return 0;" on the next call to OnCalculate?
 
Alexey Viktorov:

Igor will soon get bored too...

I just have a desire to understand

in MT5 there are a lot of pitfalls with synchronization, now the question is about that as well

imho, if the indicator uses constructions on each bar (lines, not arrows)

this cycle is enough for economical calculation:

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

if there is the first call, then prev_calculated will be = 0, in subsequent calls new bars will be recalculated


and if both indicators are written correctly, you don't need to synchronize anything additionally, everything will work, the only thing left is to compare CopyBuffer() with the required number of values of the called indicator

 
Igor Makanu:

I just want to figure it out.

in MT5 there are a lot of pitfalls with synchronisation, now the question is about that as well

imho, if the indicator uses a construction on each bar (lines, not arrows)

this cycle is enough for economical calculation:

if there is the first call, then prev_calculated will be = 0, in subsequent calls new bars will be recalculated


and if both indicators are written correctly, you don't need to synchronize anything additionally, everything will work, the only thing left is to compare CopyBuffer() with the required number of values of the called indicator

That's what I mean. It would be ok to try to synchronize before the first run, but this way............

 
Igor Makanu:

I just want to figure it out.

in MT5 there are a lot of pitfalls with synchronisation, now the question is about that as well

imho, if the indicator uses a construction on each bar (lines, not arrows)

this cycle is enough for economical calculation:

if there is the first call, then prev_calculated will be = 0, in subsequent calls new bars will be recalculated


and if both indicators are written correctly, you don't need to synchronize anything additionally, everything will work, the only thing left is to compare CopyBuffer() with the required number of values of the called indicator

if you want to understand and not oppose, you should write something like the code below:

#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);
}

compile both codes and run the second one. get something like this in the logs when running on M1 and M3 of the senior indicator:

2021.05.28 19:05:01.408 OldTF (EURUSD,M3) 0.000234 sec, 50000 bars calculated, 50000 bars total

2021.05.28 19:05:03.860 LitTF (EURUSD,M1) 0.007452 sec, 50023 bars calculated, 50023 bars total

2021.05.28 19:06:00.670 OldTF (EURUSD,M3) 0.000001 sec, calculated 1 bar, total bars 50001

2021.05.28 19:06:02.211 LitTF (EURUSD,M1) 0.008180 sec, 50024 bars calculated, 50024 bars total

2021.05.28 19:07:00.780 LitTF (EURUSD,M1) 0.000004 sec, calculated 1 bar, total bars 50025

2021.05.28 19:08:01.246 LitTF (EURUSD,M1) 0.000014 sec, settled 1 bar, total bars 50026

2021.05.28 19:09:00.959 OldTF (EURUSD,M3) 0.00000014 sec, calculated 1 bars, total bars 50002

2021.05.28 19:09:01.775 LitTF (EURUSD,M1) 0.006898 sec, 50027 bars calculated, 50027 total bars

2021.05.28 19:10:00.830 LitTF (EURUSD,M1) 0.000004 sec, calculated 1 bar, total bars 50028

even with the naked eye you can see firstly, the fastest possible way of building fast indicators, and secondly, that the pre-calc is zeroed out

In this example the indicator is forced to be completely recalculated at every new bar M3.

Alexey Viktorov:

Well, you don't have to do it.

Developers do not respond to such nonsense, Igor will soon get bored too... And stay and talk to yourself...

Just need to ask drubashka to move your outpourings into a separate thread so as not to clutter up the right one...

Look at the code above, eat your passport, sprinkle ashes on your head and shove your hubris where no one can see it.