Работа с таймсериями в Стандартной Библиотеке

 

Всех приветствую.

Сколько не искал - не могу найти описания и примеров работы с классами таймсерий типа CiHigh, CiLow и подобных.

Проблема у меня следующая: 

  • В классе СExpert стандартным образом инициализирую переменную m_high (через функцию InitHigh()), все проходит успешно.
  • Выделяю нужный размер буффера: m_high.BufferResize(1000);
  • Делаю Refresh(), 
  • m_high.Total()  возвращает единицу.

Почему еденицу ?  Вроде ж должно возвратить 1000...

Как нужно работать с классами таймсерий ? Где поглядеть мануал или примеры ?

Сколько не искал - либо применяются стандартные, сгенерированные коды, в которых не видно порядка действий, либо народ вобще не использует ни ООП, ни классов Стандартной Библиотеки.

Помогите начинающему !

Документация по MQL5: Стандартная библиотека
Документация по MQL5: Стандартная библиотека
  • www.mql5.com
Стандартная библиотека - Документация по MQL5
 

А какая перед Вами стоит задача?
 

Вызов Refresh без параметров освежает только текущее значение.
 

denkir:

А какая перед Вами стоит задача?

Задача в данном случае простейшая - перебрать значения.

Собирался сделать что-то вроде:

for(int i=0; i<m_high.Total(); ++i)

    {

    double dCurrentHigh = m_high.GetData(i);

   ... (используем полученное значение dCurrentHigh)...

    } 

Где я не прав, где смазать лыжи ?  

 

uncleVic:

Вызов Refresh без параметров освежает только текущее значение.

Хм. Приму к сведению. Мне, конечно, надо обновить весь буффер.

А  после рефреша - как получить количество элементов, хранящихся в m_high, и как последовательно их перебрать ?  Или рефреша весь буффер - и получаем значение всего буффера ? Сейчас проверю...

Насколько я понимаю из кода класса, вызов CiHigh.Refresh()  - не имеет параметров, и должен обновлять весь буффер... Что-то никак не въеду, как правильно работать с таймсериями...

 
Laryx:

Задача в данном случае простейшая - перебрать значения.

Собирался сделать что-то вроде:

for(int i=0; i<m_high.Total(); ++i)

    {

    double dCurrentHigh = m_high.GetData(i);

   ... (используем полученное значение dCurrentHigh)...

    } 

Где я не прав, где смазать лыжи ?  

А зачем тогда лезть в класс CExpertBase?

Работайте себе спокойно с CiHigh и методами GetData():

class CiHigh : public CPriceSeries
  {
public:
                     CiHigh(void);
                    ~CiHigh(void);
   //--- method of creation
   bool              Create(const string symbol,const ENUM_TIMEFRAMES period);
   //--- methods of access to data
   int               GetData(const int start_pos,const int count,double& buffer[])                const;
   int               GetData(const datetime start_time,const int count,double& buffer[])          const;
   int               GetData(const datetime start_time,const datetime stop_time,double& buffer[]) const;
  };
А для класса CExpertBase есть свой метод:
CExpertBase::SetPriceSeries(CiOpen* open,CiHigh* high,CiLow* low,CiClose* close)

И кстати член *m_high является protected...

 

Прохожусь по коду - Refresh(), хотя и требует параметров, но внутри кода - потом вызывается без параметров, и обновляет все значения.

Тем не мене, вызов Total() после этого возвращает единицу. Что-то я не вполне пойму, как работают объекты таймсерий... 

 

denkir:

А зачем тогда лезть в класс CExpertBase?

Работайте себе спокойно с CiHigh и методами GetData():

А для класса CExpertBase есть свой метод:

И кстати член *m_high является protected...

Ну я и работают этими методами, через GetData(), но надо же знать общее количество элементов в массиве !

Я думал, это Total(). Но, оказывается, нет...  

Вобще странно. Получается, что последовательные  GetData(0),GetData(1),GetData(2) - возвращают верные значения. Но Total() - возвращает единицу !

 Что-то я не пойму назначения функции  Total().

А какой функцией можно получить количество элементов внутри CiHigh и других объектов таймсерии ?  

 

Посмотрите на Базовые классы и их методы. В частности CHighBuffer. Он имеет все методы для работы с массивами...
 

denkir:

Посмотрите на Базовые классы и их методы. В частности CHighBuffer. Он имеет все методы для работы с массивами...

Да на них же я и глядел ! Метод Total() - это метод базового класса, CArray !

Я так и считал, что он и должен возвращать количество элементов. У меня получается, что я должен изменить размер буффера, и хранить это значение у себя, вместо того, чтобы в нужный момент запросить его у самого объекта.

Как выход - такая метода, конечно, работает. Но если потом я вдруг в другом месте изменю буффер, то мне надо будет искать все обращения к объекту, а это нехорошо.  

Сейчас еще раз внимательно проглядел все методы по всем объектам от наследников к родителям - единственный метод, который должен возвращать количество элементов в таймсериях, это именно Total(). Почему он возвращает единицу - мне непонятно, тем более, что метод GetData(0) - вполне нормально работает с индексами больше единицы.

 

Сейчас еще проверил - удивительно.

GetData() - возвращает правильные данные по всем индексам. Однако, при задании индекса, превышающего установленный размер буффера - возвращается нуль. (проверялось на объекте CiTime, чтобы проще было понимать, с какого времени берутся данные). То есть - размер буффера установлен, и обновление проходит правильно, но запрос количества элементов - возвращает единицу. Нифига не пойму.

Попробую поискать примеры кода, работающего с таймсериями... Как там запрашивается размер буффера таймсерии...

 

 

Laryx:

...Как выход - такая метода, конечно, работает. Но если потом я вдруг в другом месте изменю буффер, то мне надо будет искать все обращения к объекту, а это нехорошо.  

А что мешает самому запрограммировать потомок класса CHighBuffer?

Посмотрите к примеру:

CHighBuffer myHighBuff;
myHighBuff.SetSymbolPeriod(_Symbol,_Period);
myHighBuff.Resize(55);
myHighBuff.Refresh();
int arr_size=myHighBuff.Total();
 

denkir, да, конечно, можно самому объявлять буфферы, и самому их заполнять - но хотелось бы выдержать идеологию Стандартной Библиотеки.

Это особенно важно с учетом того, что MQL не поддерживает указатели на массивы - для того, чтобы один массив использовать в разных местах, нужен вот такой объект-обертка, чтобы везде, где надо - использовать указатель на него.

Сейчас поглядел внимательно код - интересное дело получается.

Внутри объекта CiTime имеется список буфферов.

В списке - один буффер типа CTimeBuffer.

В этом буффере и хранятся данные по времени таймсерии (как я понимаю, для остальных объектов - ситуация такая же).

Количество элементов объекта хранится в переменной  m_data_total. И вот тут и получается двусмысленность. Как я понял, эта переменная существует и в объекте CiTime, и в объекте  CTimeBuffer. Так вот, эта переменная внутри буффера - обозначает количество элементов буффера - именно она является количеством элементов данных. А вот эта переменная внутри класса CiTime - инициализируется один раз, в момент создания и добавления буффера, и указывает на количество этих самых буфферов, а вовсе не элементов данных !

Сколько я ни глядел - нет ни одного метода, который бы позволил внешней процедуре запросить у  CiTime количество элементов данных, хранящихся в нем - эти элементы хранятся в переменной CTimeBuffer, у которой своя функция Total().

 

Неприятно.

Это что, баг или фича ? Написать в сервисдеск, что ли ?