Custom symbols. Errors, bugs, questions, suggestions. - page 27

 
Stanislav Korotky:

Adding one-to-one ticks (in particular from EURUSD on MQ Demo) to an empty new custom symbol gives error 5310 (not immediately, but in a loop from an arbitrary date).

What's wrong? How do I know which specific ticks are being scolded? Putting arrays into log - no chronological violation there.

Try to insert the check for ticks copying.
I have an indicator on the real time data in tick processing, when copying CopyClose, sometimes it triggers copying error.
I don't understand what may be the reason. Maybe in your case there is a copying error.

Also, in CopyTicks, you copy a lot of ticks Limit, and then in the while loop, i.e. every iteration you copy a big array of ticks.
And in CustomTicksAdd you pass the same large number of ticks to the array.
Try to copy one tick and pass one tick.
You are running in a while loop.

input int Limit = 10000;
input datetime Start = D'2020.06.01';

int fillArray(ulong &_start)
{
  MqlTick array[];
  int size = CopyTicks(_Symbol, array, COPY_TICKS_ALL, _start, Limit);

  if(size <= 0) 
  {
     Print("Ошибка копирования ценовых данных "+_Symbol+" "+(string)size+" ",GetLastError());
     return(size);
  }

  if(size > 0)
  {
    _start = array[size - 1].time_msc + 1;
    if(CustomTicksAdd(symbolName, array) == -1)
    {
      Print("Error:", GetLastError());
      return(-1);
    }
  }
  return(size);
}

...
{
  ulong startMsc = (ulong)Start * 1000;
  while(fillArray(startMsc) > 0);
}
Added. Not related to custom symbols.
I just caught in the indicator, in the tick real time the cause of copy error with period M5 by CopyClose function.
Internet connection was cut off for some seconds and after connection appeared the copy error 4401The requested history was not found
It`s strange, the period M5 has not changed to a new bar yet, but the error has popped up.
 
Roman:

Try to insert check for copying ticks.
In my indicator on real time data in tick processing, when copying CopyClose, sometimes a copying error occurs.
I don't understand what may be the reason. Maybe in your case there is a copying error.

Also, in CopyTicks, you copy a lot of ticks Limit, and then in the while loop, i.e. every iteration you copy a big array of ticks.
And in CustomTicksAdd you pass the same large number of ticks to the array.
Try to copy one tick, and pass one tick.

There are no copying errors, the code gets a normal value of the number of copied ticks (size), the array is filled with normal data all the time. Limit can be changed, but an error occurs at any meaningful value from one to several thousand. Copying all the ticks at once (as in some codes) is obviously wrong because it can cause a memory allocation error and lock the thread for a long time without being able to show the user progress. And copying ticks in small batches of 10 (let alone 1) slows down the whole process - this is unacceptable.

The suggested variant is optimal. And even if it's debatable for someone, formally the code is correct (or cite where I'm wrong) and current behavior is error, i.e. ticks must be added without code 5310.

Also, there is still a long standing problem with clearing the ticks database. Call CustomTicksDelete(symbolName, 0, LONG_MAX); doesn't want to delete all ticks and leaves some (it is observed not constantly, but about once in a while). If you restart the Expert Advisor, the custom symbol is cleared completely. As in case of CopyTicks - no errors.

 
If you want to write ticks without generating more OnTick events, it may be better to use a different function.
 
Stanislav Korotky:

Maybe there are ticks with the same ms at the junction of the packs and this counts as an error?

Just a guess

 
Andrey Khatimlianskii:

Maybe there are ticks with the same ms at the junction of the packs and this counts as an error?

Just a guess.

You can see from the code that there are duplicate ticks. In this case, the flags of ticks may not correspond to each other.

 
fxsaber:
If you need to write ticks without generating more OnTick events, you might be better off using a different function.

I agree. I'll give it a try. But I see no reason why the current method shouldn't work.

 
Stanislav Korotky:

There are no copying errors, the code gets a normal value of the number of copied ticks (size), the array is filled with normal data all the time. Limit can be changed, but an error occurs at any meaningful value from one to several thousands. Copying all the ticks at once (as in some codes) is obviously wrong because it can cause a memory allocation error and lock the thread for a long time without being able to show the user progress. And copying ticks in small batches of 10 (let alone 1) slows down the whole process.

The suggested variant is optimal. And even if it's questionable for someone, formally the code is correct (or cite where I'm wrong) and current behavior is error, i.e. ticks must be added without code 5310.

Also, there is still a long standing problem with clearing the ticks database. Call CustomTicksDelete(symbolName, 0, LONG_MAX); doesn't want to delete all ticks and leaves some (it is observed not constantly, but about once in a while). If you restart the Expert Advisor, the custom symbol is cleared completely. As in case of CopyTicks - no errors.

ERR_CUSTOM_TICKS_WRONG_ORDER

5310

Arrayof ticksnot ordered by time


It's possible that you don't have time to delete ticks in big batches, because you are overwriting already existing ones in the next iteration.
That is, they superimpose on each other as an array, while it flies without delay, so the memory has no time to be cleared when another pack arrives.
That's why I suggested to add one tick at a time, I copied one tick at a time, no problems.

As for clearing ticks database, I don't like constant LONG_MAX in this case.
The help of the CustomTicksDelete function says, Time of the last tick in the price history from the specified range to be deleted. The time in milliseconds since 01.01.1970.
And LONG_MAX is much larger than this value. That is, a larger value is passed, for which this parameter is not designed.
Try to use the number corresponding to the milliseconds digit, i.e. 13 values.

 
fxsaber:

You can see from the code that there are duplicate ticks. In this case, elementary flags of ticks may not correspond.

Are the duplicated ticks in receiving array CopyTicks? How is it clear, that these are duplicated ticks, and not the same ticks (ticks don't have unique identifiers, after all)? Even if there are duplicates, in theory, the ticks with equal cutoffs don't break the sequence. Finally, the question arises - how are the duplicates formed?

 
Roman:

ERR_CUSTOM_TICKS_WRONG_ORDER

5310

Arrayof ticksis not ordered by time


It's possible that the big packs of ticks don't have time to be deleted, since you are overwriting the ones you already have in the next iteration.
That is, they superimpose on each other as an array, while it flies without delays, so the memory has no time to be cleared when another pack arrives.
That's why I suggested to add one tick at a time, I copied one tick at a time, there were no problems.

Not a word about deletion, nothing is overwritten. Iterations are timed without overlap. Always in an empty custom character - either a new one, or after successful deletion of all ticks.

 
Stanislav Korotky:

Duplicate ticks in the receiving array CopyTicks? How is it clear that these are duplicate ticks and not identical ticks (ticks don't have unique identifiers, after all)? Even if there are duplicates, in theory, the ticks with equal cutoffs don't break the sequence. Finally, a question arises - how are the duplicates formed?

I've looked at the code more closely. You are skipping ticks when receiving in portions. There may be a situation when Ticks[Limit - 1].time_msc == Ticks[Limit + k], k >= 0.

Accordingly, when you add with a skip, the flags may not match.


Make sure that all historical ticks with the same time are at the end of the portion. That is, the beginning of the next chunk should have a different time. Otherwise there will be losses even when writing to custom.

If you want to use CopyTicks, the easiest way is to discard the most extreme ticks with the longest time from the received pack. And make _start equal to this time.