Testing 'CopyTicks' - page 24

 
Alexey Kozitsyn:

Why?

int  CopyTicks(
   string           symbol_name,           // имя символа
   MqlTick&         ticks_array[],         // массив для приёма тиков
   uint             flags=COPY_TICKS_ALL,  // флаг, определяющий тип получаемых тиков
   ulong            from=0,                // дата, начиная с которой запрашиваются тики
   uint             count=0                // количество тиков, которые необходимо получить
   );
Highlighted in bold. The array at the end is a rejection of default values.
 
fxsaber:
int  CopyTicks(
   string           symbol_name,           // имя символа
   MqlTick&         ticks_array[],         // массив для приёма тиков
   uint             flags=COPY_TICKS_ALL,  // флаг, определяющий тип получаемых тиков
   ulong            from=0,                // дата, начиная с которой запрашиваются тики
   uint             count=0                // количество тиков, которые необходимо получить
   );
Highlighted in bold.
Not highlighted, but probably answered above...
 
fxsaber:
int  CopyTicks(
   string           symbol_name,           // имя символа
   MqlTick&         ticks_array[],         // массив для приёма тиков
   uint             flags=COPY_TICKS_ALL,  // флаг, определяющий тип получаемых тиков
   ulong            from=0,                // дата, начиная с которой запрашиваются тики
   uint             count=0                // количество тиков, которые необходимо получить
   );
I put it in bold. Array at the end - avoid default values.

Yes, the size of the ticks in the cache can be explicitly allocated in the documentation. If you want to get the whole cache - look at the documentation and ask for the required number with the function, with parameters like here:

intCopyBuffer(
intindicator_handle,// indicator handle
intbuffer_num,// indicator buffer number
intstart_pos,//where to start
intcount,// how many we copy
doublebuffer[]// array where data will be copied
);

Everything has already been made up, why should you invent something new?

 
Alexey Kozitsyn:

I think it's far more important to do a date-to-date download than to try to keep the default settings.

So from date to date it will be. CopyTicks trying to match in syntax to Copy-functions only because of presence of Copy in the name is not convenient. Convenient and justified is when you can do preprocessor stuff like this

// Позволяет, как в MT4, работать с таймсериями: Open[Pos], High[Pos], Low[Pos], Close[Pos], Time[Pos], Volume[Pos].
// А так же задает привычные MT4-функции: iOpen, iHigh, iLow, iClose, iTime, iVolume.
#define DEFINE_TIMESERIE(NAME,FUNC,T)                                                                         \
  class CLASS##NAME                                                                                           \
  {                                                                                                           \
  public:                                                                                                     \
    static T Get( const string Symb, const int TimeFrame, const int iShift )                                  \
    {                                                                                                         \
      T tValue[];                                                                                             \
                                                                                                              \
      return((Copy##FUNC((Symb == NULL) ? _Symbol : Symb, _Period, iShift, 1, tValue) > 0) ? tValue[0] : -1); \
    }                                                                                                         \
                                                                                                              \
    T operator []( const int iPos ) const                                                                     \
    {                                                                                                         \
      return(CLASS##NAME::Get(_Symbol, _Period, iPos));                                                       \
    }                                                                                                         \
  };                                                                                                          \
                                                                                                              \
  CLASS##NAME NAME;                                                                                           \
                                                                                                              \
  T i##NAME( const string Symb, const int TimeFrame, const int iShift )                                       \
  {                                                                                                           \
    return(CLASS##NAME::Get(Symb, TimeFrame, iShift));                                                        \
  }

DEFINE_TIMESERIE(Volume, TickVolume, long)
DEFINE_TIMESERIE(Time, Time, datetime)
DEFINE_TIMESERIE(Open, Open, double)
DEFINE_TIMESERIE(High, High, double)
DEFINE_TIMESERIE(Low, Low, double)
DEFINE_TIMESERIE(Close, Close, double)
And you can't do it for CopyTicks because there are two different physical threads (TRADE and INFO) and one synthetic thread (ALL) - flags.
 
fxsaber:

So from date to date it will be. CopyTicks trying to match the syntax to Copy-functions just because of the presence of Copy in the name is not convenient. Convenient and justified is when you can do preprocessor stuff like this.

#define DEFINE_TIMESERIE(NAME,FUNC,T)                                                                         \
  class CLASS##NAME                                                                                           \
  {                                                                                                           \
  public:                                                                                                     \
    static T Get( const string Symb, const int TimeFrame, const int iShift )                                  \
    {                                                                                                         \
      T tValue[];                                                                                             \
                                                                                                              \
      return((Copy##FUNC((Symb == NULL) ? _Symbol : Symb, _Period, iShift, 1, tValue) > 0) ? tValue[0] : -1); \
    }                                                                                                         \
                                                                                                              \
    T operator []( const int iPos ) const                                                                     \
    {                                                                                                         \
      return(CLASS##NAME::Get(_Symbol, _Period, iPos));                                                       \
    }                                                                                                         \
  };                                                                                                          \
                                                                                                              \
  CLASS##NAME NAME;                                                                                           \
                                                                                                              \
  T i##NAME( const string Symb, const int TimeFrame, const int iShift )                                       \
  {                                                                                                           \
    return(CLASS##NAME::Get(Symb, TimeFrame, iShift));                                                        \
  }

DEFINE_TIMESERIE(Volume, TickVolume, long)
DEFINE_TIMESERIE(Time, Time, datetime)
DEFINE_TIMESERIE(Open, Open, double)
DEFINE_TIMESERIE(High, High, double)
DEFINE_TIMESERIE(Low, Low, double)
DEFINE_TIMESERIE(Close, Close, double)
And for CopyTicks this kind of thing cannot be done, because there are two different physical threads (TRADE and INFO) and one synthetic (ALL) - flags.

Before you appeared on the forum, I hadn't encountered this way of writing, for which I, of course, thank you, but I'm not sure that many programmers would find it useful.

 
fxsaber:

On your demo, indeed it is. On BCS it is not.

Network 'xxx': authorized on BCS-MetaTrader5 through Access Server #2 (ping: 46.66 ms)


2016.10.18 15:12:32.949 Test14 (Si-12.16,M1)    Time: 29089 msc for 1503 records
2016.10.18 15:12:32.822 Test14 (Si-12.16,M1)    Time: 33207 msc for 1501 records
2016.10.18 15:12:32.639 Test14 (Si-12.16,M1)    Time: 21389 msc for 1500 records
2016.10.18 15:12:31.959 Test14 (Si-12.16,M1)    Time: 21926 msc for 1500 records

And on Alpari it's not good at all.

Network 'xxx': authorized on Alpari-MT5 through mt5.nl.3 (ping: 61.87 ms)

2016.10.18 15:14:47.159 Test14 (GBPUSD,M1)      Time: 31086 msc for 1836 records
2016.10.18 15:14:46.999 Test14 (GBPUSD,M1)      Time: 30698 msc for 1836 records
2016.10.18 15:14:46.779 Test14 (GBPUSD,M1)      Time: 46306 msc for 1836 records
2016.10.18 15:14:46.612 Test14 (GBPUSD,M1)      Time: 30440 msc for 1836 records
2016.10.18 15:14:46.532 Test14 (GBPUSD,M1)      Time: 36227 msc for 1836 records

Spoke above about the inconvenience of copytix. The presented indicator slows down due to the fact that I have to call copytix several times. And all the lags are because of it. The point is this

The solution has been proposed.

Now to download ticks between dates, you need to make requests for ANY number of ticks, starting from the starting date. And then look each time, and whether it reached the end date. And given that each copytix request is very expensive, and you get such brakes.

Data from real opening, only fresh ticks are loaded:

2016.10.20 18:47:06.499 GetTickHistory: Получено 4 тиков за 46 мкс (пинг = 62214 мкс)
2016.10.20 18:47:06.499 GetTickHistory: Получены все доступные тики. Время [0]: 2016.10.20 16:47
2016.10.20 18:47:06.499 GetTickHistory: Получено 3 тиков за 20 мкс (пинг = 62214 мкс)
2016.10.20 18:47:06.499 GetTickHistory: Получены все доступные тики. Время [0]: 2016.10.20 16:47
2016.10.20 18:47:06.499 GetTickHistory: Получено 3 тиков за 19 мкс (пинг = 62214 мкс)
2016.10.20 18:47:06.499 GetTickHistory: Получены все доступные тики. Время [0]: 2016.10.20 16:47
2016.10.20 18:47:06.540 GetTickHistory: Получено 8 тиков за 107 мкс (пинг = 62214 мкс)
2016.10.20 18:47:06.540 GetTickHistory: Получены все доступные тики. Время [0]: 2016.10.20 16:47
2016.10.20 18:47:06.540 GetTickHistory: Получено 5 тиков за 19 мкс (пинг = 62214 мкс)
2016.10.20 18:47:06.540 GetTickHistory: Получены все доступные тики. Время [0]: 2016.10.20 16:47
2016.10.20 18:47:06.540 GetTickHistory: Получено 5 тиков за 19 мкс (пинг = 62214 мкс)
2016.10.20 18:47:06.540 GetTickHistory: Получены все доступные тики. Время [0]: 2016.10.20 16:47
2016.10.20 18:47:06.540 GetTickHistory: Получено 5 тиков за 18 мкс (пинг = 62214 мкс)
2016.10.20 18:47:06.540 GetTickHistory: Получены все доступные тики. Время [0]: 2016.10.20 16:47
COPY_TICKS_TRADE!
 
CopyTicks() seems to be asynchronous function? Often ticks arrive for candlesticks that haven't opened yet...
 
Alexey Kozitsyn:
CopyTicks() seems to be an asynchronous function?
Yes.
 
I'd like to hear from developers about CopyTicks() in tester... I have bad suspicions about it. I'm interested again in working with COPY_TICKS_TRADE!
 

Tired of the terminal. The script

void OnStart()
{
  MqlTick Ticks[];
  
  Print(CopyTicks(_Symbol, Ticks));
  Print(GetLastError());
}

hangs. Manually deleting it will log it out.

2016.10.28 16:48:57.737 Test (GBPUSD,M1)        4401
2016.10.28 16:48:57.737 Test (GBPUSD,M1)        -1

Changing TF and symbol - similar. After restarting it works.