Работа с таймсериями в библиотеке DoEasy (Часть 54): Классы-наследники абстрактного базового индикатора
Содержание
- Концепция
- Доработка классов библиотеки
- Классы объектов-индикаторов
- Коллекция объектов-индикаторов
- Тестирование
- Что дальше
Концепция
В прошлой статье мы рассмотрели создание базового абстрактного объекта-индикатора. Сегодня создадим его объекты-наследники, в которых будет уточняться информация о конкретном создаваемом объекте-индикаторе. Все эти объекты мы поместим в коллекцию индикаторов, из которой можно будет получать данные и свойства каждого созданного индикатора.
Концепция объектов-наследников полностью соответствует концепции построения объектов в библиотеке и их взаимосвязям. Коллекция же индикаторов позволит нам быстро добавить всем объектам-индикаторам событийный функционал в дальнейшем, что позволит нам легко задать отслеживаемые события индикаторов и использовать эти события в своих программах.
Доработка классов библиотеки
Как обычно, начнём с добавления необходимых текстовых сообщений библиотеки.
В файле \MQL5\Include\DoEasy\Data.mqh впишем индексы новых сообщений:
//--- CIndicatorDE MSG_LIB_TEXT_IND_TEXT_STATUS, // Статус индикатора MSG_LIB_TEXT_IND_TEXT_STATUS_STANDART, // Стандартный индикатор MSG_LIB_TEXT_IND_TEXT_STATUS_CUSTOM, // Пользовательский индикатор MSG_LIB_TEXT_IND_TEXT_TYPE, // Тип индикатора MSG_LIB_TEXT_IND_TEXT_TIMEFRAME, // Таймфрейм индикатора MSG_LIB_TEXT_IND_TEXT_HANDLE, // Хэндл индикатора MSG_LIB_TEXT_IND_TEXT_GROUP, // Группа индикатора MSG_LIB_TEXT_IND_TEXT_GROUP_TREND, // Трендовый индикатор MSG_LIB_TEXT_IND_TEXT_GROUP_OSCILLATOR, // Осциллятор MSG_LIB_TEXT_IND_TEXT_GROUP_VOLUMES, // Объёмы MSG_LIB_TEXT_IND_TEXT_GROUP_ARROWS, // Стрелочный индикатор MSG_LIB_TEXT_IND_TEXT_EMPTY_VALUE, // Пустое значение для построения, для которого нет отрисовки MSG_LIB_TEXT_IND_TEXT_SYMBOL, // Символ индикатора MSG_LIB_TEXT_IND_TEXT_NAME, // Имя индикатора MSG_LIB_TEXT_IND_TEXT_SHORTNAME, // Короткое имя индикатора //--- CIndicatorsCollection MSG_LIB_SYS_FAILED_ADD_IND_TO_LIST, // Ошибка. Не удалось добавить объект-индикатор в список }; //+------------------------------------------------------------------+
и далее впишем новые сообщения, соответствующие вновь добавленным индексам:
{"Статус индикатора","Indicator status"}, {"Стандартный индикатор","Standard indicator"}, {"Пользовательский индикатор","Custom indicator"}, {"Тип индикатора","Indicator type"}, {"Таймфрейм индикатора","Indicator timeframe"}, {"Хэндл индикатора","Indicator handle"}, {"Группа индикатора","Indicator group"}, {"Трендовый индикатор","Trend indicator"}, {"Осциллятор","Solid lineOscillator"}, {"Объёмы","Volumes"}, {"Стрелочный индикатор","Arrow indicator"}, {"Пустое значение для построения, для которого нет отрисовки","Empty value for plotting, for which there is no drawing"}, {"Символ индикатора","Indicator symbol"}, {"Имя индикатора","Indicator name"}, {"Короткое имя индикатора","Indicator shortname"}, {"Ошибка. Не удалось добавить объект-индикатор в список","Error. Failed to add indicator object to list"}, }; //+---------------------------------------------------------------------+
При создании класса объекта абстрактного индикатора в прошлой статье мы не вписали одно из целочисленных свойств объекта — тип стандартного индикатора. Этот тип будет соответствовать типам перечисления ENUM_INDICATOR, и нужен будет для поиска конкретного индикатора.
Если мы хотим найти все индикаторы MACD, хранящиеся в коллекции, то первым делом мы должны получить список всех индикаторов MACD, находящихся в коллекции. Для этого нам необходимо отфильтровать полный список коллекции индикаторов по типу IND_MACD, а уже потом в полученном списке, в котором будут лежать только IND_MACD, делать выбор по другим искомым свойствам.
Допишем новое свойство объекта-индикатора в файл \MQL5\Include\DoEasy\Defines.mqh:
//+------------------------------------------------------------------+ //| Целочисленные свойства индикатора | //+------------------------------------------------------------------+ enum ENUM_INDICATOR_PROP_INTEGER { INDICATOR_PROP_STATUS = 0, // Статус индикатора (из перечисления ENUM_INDICATOR_STATUS) INDICATOR_PROP_TYPE, // Тип индикатора (из перечисления ENUM_INDICATOR) INDICATOR_PROP_TIMEFRAME, // Таймфрейм индикатора INDICATOR_PROP_HANDLE, // Хэндл индикатора INDICATOR_PROP_GROUP, // Группа индикатора }; #define INDICATOR_PROP_INTEGER_TOTAL (5) // Общее количество целочисленных свойств индикатора #define INDICATOR_PROP_INTEGER_SKIP (0) // Количество неиспользуемых в сортировке свойств индикатора //+------------------------------------------------------------------+
и увеличим количество целочисленных свойств с 4 до 5.
При добавлении нового свойства объекту нам нужно задать возможность поиска и сортировки объектов по этому свойству.
Добавим новый критерий сортировки в перечисление:
//+------------------------------------------------------------------+ //| Возможные критерии сортировки индикаторов | //+------------------------------------------------------------------+ #define FIRST_INDICATOR_DBL_PROP (INDICATOR_PROP_INTEGER_TOTAL-INDICATOR_PROP_INTEGER_SKIP) #define FIRST_INDICATOR_STR_PROP (INDICATOR_PROP_INTEGER_TOTAL-INDICATOR_PROP_INTEGER_SKIP+INDICATOR_PROP_DOUBLE_TOTAL-INDICATOR_PROP_DOUBLE_SKIP) enum ENUM_SORT_INDICATOR_MODE { //--- Сортировка по целочисленным свойствам SORT_BY_INDICATOR_INDEX_STATUS = 0, // Сортировать по статусу индикатора SORT_BY_INDICATOR_TYPE, // Сортировать по типу индикатора SORT_BY_INDICATOR_TIMEFRAME, // Сортировать по таймфрейму индикатора SORT_BY_INDICATOR_HANDLE, // Сортировать по хэндлу индикатора SORT_BY_INDICATOR_GROUP, // Сортировать по группе индикатора //--- Сортировка по вещественным свойствам SORT_BY_INDICATOR_EMPTY_VALUE = FIRST_INDICATOR_DBL_PROP,// Сортировать по пустому значению для построения, для которого нет отрисовки //--- Сортировка по строковым свойствам SORT_BY_INDICATOR_SYMBOL = FIRST_INDICATOR_STR_PROP, // Сортировать по символу индикатора SORT_BY_INDICATOR_NAME, // Сортировать по имени индикатора SORT_BY_INDICATOR_SHORTNAME, // Сортировать по короткому имени индикатора }; //+------------------------------------------------------------------+
Доработаем класс объекта абстрактного индикатора в файле \MQL5\Include\DoEasy\Objects\Indicators\IndicatorDE.mqh.
Перенесём массив структур параметров индикатора из приватной секции класса в защищённую (этот массив теперь станет доступен классам-наследникам), а в приватной секции объявим переменную для хранения описания типа индикатора:
//+------------------------------------------------------------------+ //| Класс абстрактного индикатора | //+------------------------------------------------------------------+ class CIndicatorDE : public CBaseObj { protected: MqlParam m_mql_param[]; // Массив параметров индикатора private: long m_long_prop[INDICATOR_PROP_INTEGER_TOTAL]; // Целочисленные свойства double m_double_prop[INDICATOR_PROP_DOUBLE_TOTAL]; // Вещественные свойства string m_string_prop[INDICATOR_PROP_STRING_TOTAL]; // Строковые свойства string m_ind_type; // Описание типа индикатора
В публичную секцию класса впишем два метода — для возврата типа индикатора и для возврата описания типа индикатора:
public: //--- Конструктор по умолчанию CIndicatorDE(void){;} //--- Деструктор ~CIndicatorDE(void); //--- Устанавливает (1) целочисленное, (2) вещественное и (3) строковое свойство буфера void SetProperty(ENUM_INDICATOR_PROP_INTEGER property,long value) { this.m_long_prop[property]=value; } void SetProperty(ENUM_INDICATOR_PROP_DOUBLE property,double value) { this.m_double_prop[this.IndexProp(property)]=value; } void SetProperty(ENUM_INDICATOR_PROP_STRING property,string value) { this.m_string_prop[this.IndexProp(property)]=value; } //--- Возвращает из массива свойств (1) целочисленное, (2) вещественное и (3) строковое свойство буфера long GetProperty(ENUM_INDICATOR_PROP_INTEGER property) const { return this.m_long_prop[property]; } double GetProperty(ENUM_INDICATOR_PROP_DOUBLE property) const { return this.m_double_prop[this.IndexProp(property)]; } string GetProperty(ENUM_INDICATOR_PROP_STRING property) const { return this.m_string_prop[this.IndexProp(property)]; } //--- Возвращает описание (1) целочисленного, (2) вещественного и (3) строкового свойства буфера string GetPropertyDescription(ENUM_INDICATOR_PROP_INTEGER property); string GetPropertyDescription(ENUM_INDICATOR_PROP_DOUBLE property); string GetPropertyDescription(ENUM_INDICATOR_PROP_STRING property); //--- Возвращает флаг поддержания буфером данного свойства virtual bool SupportProperty(ENUM_INDICATOR_PROP_INTEGER property) { return true; } virtual bool SupportProperty(ENUM_INDICATOR_PROP_DOUBLE property) { return true; } virtual bool SupportProperty(ENUM_INDICATOR_PROP_STRING property) { return true; } //--- Сравнивает объекты CIndicatorDE между собой по всем возможным свойствам (для сортировки списков по указанному свойству объекта-индикатора) virtual int Compare(const CObject *node,const int mode=0) const; //--- Сравнивает объекты CIndicatorDE между собой по всем свойствам (для поиска равных объектов-индикаторов) bool IsEqual(CIndicatorDE* compared_obj) const; //--- Устанавливает (1) группу, (2) пустое значение буферов, (3) имя, (4) короткое имя индикатора void SetGroup(const ENUM_INDICATOR_GROUP group) { this.SetProperty(INDICATOR_PROP_GROUP,group); } void SetEmptyValue(const double value) { this.SetProperty(INDICATOR_PROP_EMPTY_VALUE,value); } void SetName(const string name) { this.SetProperty(INDICATOR_PROP_NAME,name); } void SetShortName(const string shortname) { this.SetProperty(INDICATOR_PROP_SHORTNAME,shortname); } //--- Возвращает (1) статус, (2) группу, (3) таймфрейм, (4) хэндл, (5) пустое значение буферов, (6) имя, (7) короткое имя, (8) символ, (9) тип индикатора ENUM_INDICATOR_STATUS Status(void) const { return (ENUM_INDICATOR_STATUS)this.GetProperty(INDICATOR_PROP_STATUS);} ENUM_INDICATOR_GROUP Group(void) const { return (ENUM_INDICATOR_GROUP)this.GetProperty(INDICATOR_PROP_GROUP); } ENUM_TIMEFRAMES Timeframe(void) const { return (ENUM_TIMEFRAMES)this.GetProperty(INDICATOR_PROP_TIMEFRAME); } ENUM_INDICATOR TypeIndicator(void) const { return (ENUM_INDICATOR)this.GetProperty(INDICATOR_PROP_TYPE); } int Handle(void) const { return (int)this.GetProperty(INDICATOR_PROP_HANDLE); } double EmptyValue(void) const { return this.GetProperty(INDICATOR_PROP_EMPTY_VALUE); } string Name(void) const { return this.GetProperty(INDICATOR_PROP_NAME); } string ShortName(void) const { return this.GetProperty(INDICATOR_PROP_SHORTNAME); } string Symbol(void) const { return this.GetProperty(INDICATOR_PROP_SYMBOL); } //--- Возвращает описание (1) типа, (2) статуса, (3) группы, (4) таймфрейма, (5) пустого значения индикатора string GetTypeDescription(void) const { return m_ind_type; } string GetStatusDescription(void) const; string GetGroupDescription(void) const; string GetTimeframeDescription(void) const; string GetEmptyValueDescription(void) const; //--- Выводит в журнал описание свойств объекта-индикатора (full_prop=true - все свойства, false - только поддерживаемые) void Print(const bool full_prop=false); //--- Выводит в журнал краткое описание объекта-индикатора (реализация в наследниках) virtual void PrintShort(void) {;} }; //+------------------------------------------------------------------+
В закрытом параметрическом конструкторе извлечём подстроку из входного параметра типа индикатора, чтобы оставить только само наименование индикатора (например, из IND_MACD останется только MACD, что и будет описанием типа индикатора), а сам тип индикатора запишем в свойства объекта:
//+------------------------------------------------------------------+ //| Закрытый параметрический конструктор | //+------------------------------------------------------------------+ CIndicatorDE::CIndicatorDE(ENUM_INDICATOR ind_type, string symbol, ENUM_TIMEFRAMES timeframe, ENUM_INDICATOR_STATUS status, ENUM_INDICATOR_GROUP group, string name, string shortname, MqlParam &mql_params[]) { //--- Устанавливаем идентификатор коллекции объекту this.m_type=COLLECTION_INDICATORS_ID; //--- Записываем описание типа индикатора this.m_ind_type=::StringSubstr(::EnumToString(ind_type),4); //--- Если размер переданного в конструктор массива параметров больше нуля, то //--- заполняем массив параметров объекта данными из переданного в конструктор массива int count=::ArrayResize(m_mql_param,::ArraySize(mql_params)); for(int i=0;i<count;i++) { this.m_mql_param[i].type=mql_params[i].type; this.m_mql_param[i].double_value=mql_params[i].double_value; this.m_mql_param[i].integer_value=mql_params[i].integer_value; this.m_mql_param[i].string_value=mql_params[i].string_value; } //--- Создаём хэндл индикатора int handle=::IndicatorCreate(symbol,timeframe,ind_type,count,this.m_mql_param); //--- Сохранение целочисленных свойств this.m_long_prop[INDICATOR_PROP_STATUS] = status; this.m_long_prop[INDICATOR_PROP_TYPE] = ind_type; this.m_long_prop[INDICATOR_PROP_GROUP] = group; this.m_long_prop[INDICATOR_PROP_TIMEFRAME] = timeframe; this.m_long_prop[INDICATOR_PROP_HANDLE] = handle; //--- Сохранение вещественных свойств this.m_double_prop[this.IndexProp(INDICATOR_PROP_EMPTY_VALUE)]=EMPTY_VALUE; //--- Сохранение строковых свойств this.m_string_prop[this.IndexProp(INDICATOR_PROP_SYMBOL)] = (symbol==NULL || symbol=="" ? ::Symbol() : symbol); this.m_string_prop[this.IndexProp(INDICATOR_PROP_NAME)] = name; this.m_string_prop[this.IndexProp(INDICATOR_PROP_SHORTNAME)]= shortname; } //+------------------------------------------------------------------+
В методе, возвращающем описание целочисленного свойства индикатора, добавим блок кода для возврата описания типа индикатора:
//+------------------------------------------------------------------+ //| Возвращает описание целочисленного свойства индикатора | //+------------------------------------------------------------------+ string CIndicatorDE::GetPropertyDescription(ENUM_INDICATOR_PROP_INTEGER property) { return ( property==INDICATOR_PROP_STATUS ? CMessage::Text(MSG_LIB_TEXT_IND_TEXT_STATUS)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.GetStatusDescription() ) : property==INDICATOR_PROP_TYPE ? CMessage::Text(MSG_LIB_TEXT_IND_TEXT_TYPE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.GetTypeDescription() ) : property==INDICATOR_PROP_GROUP ? CMessage::Text(MSG_LIB_TEXT_IND_TEXT_GROUP)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.GetGroupDescription() ) : property==INDICATOR_PROP_TIMEFRAME ? CMessage::Text(MSG_LIB_TEXT_IND_TEXT_TIMEFRAME)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+this.GetTimeframeDescription() ) : property==INDICATOR_PROP_HANDLE ? CMessage::Text(MSG_LIB_TEXT_IND_TEXT_HANDLE)+ (!this.SupportProperty(property) ? ": "+CMessage::Text(MSG_LIB_PROP_NOT_SUPPORTED) : ": "+(string)this.GetProperty(property) ) : "" ); } //+------------------------------------------------------------------+
Классы объектов индикаторов
Теперь нам предстоит создать объекты-наследники базового абстрактного индикатора, которые будут уточнять всю информацию по создаваемому объекту-индикатору, и именно эти классы и будут служить для создания индикаторов разных типов и получению данных от них.
В каталоге \MQL5\Include\DoEasy\Objects\Indicators\ создадим новую папку Standart, а в ней новый файл IndAC.mqh класса CIndAC стандартного индикатора Accelerator Oscillator, унаследованного от базового класса абстрактного индикатора, файл которого подключен к листингу этого класса.
Так как класс будет небольшим, то сразу же посмотрим его полный листинг:
//+------------------------------------------------------------------+ //| IndAC.mqh | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/ru/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/ru/users/artmedia70" //+------------------------------------------------------------------+ //| Включаемые файлы | //+------------------------------------------------------------------+ #include "..\\IndicatorDE.mqh" //+------------------------------------------------------------------+ //| Стандартный индикатор Accelerator Oscillator | //+------------------------------------------------------------------+ class CIndAC : public CIndicatorDE { private: public: //--- Конструктор CIndAC(const string symbol,const ENUM_TIMEFRAMES timeframe,MqlParam &mql_param[]) : CIndicatorDE(IND_AC,symbol,timeframe, INDICATOR_STATUS_STANDART, INDICATOR_GROUP_OSCILLATOR, "Accelerator Oscillator", "AC("+symbol+","+TimeframeDescription(timeframe)+")",mql_param) {} //--- Поддерживаемые свойства индикатора (1) вещественные, (2) целочисленные virtual bool SupportProperty(ENUM_INDICATOR_PROP_DOUBLE property); virtual bool SupportProperty(ENUM_INDICATOR_PROP_INTEGER property); //--- Выводит в журнал краткое описание объекта-индикатора virtual void PrintShort(void); }; //+------------------------------------------------------------------+ //| Возвращает истину, если индикатор поддерживает переданное | //| целочисленное свойство, возвращает ложь в противном случае | //+------------------------------------------------------------------+ bool CIndAC::SupportProperty(ENUM_INDICATOR_PROP_INTEGER property) { return true; } //+------------------------------------------------------------------+ //| Возвращает истину, если индикатор поддерживает переданное | //| вещественное свойство, возвращает ложь в противном случае | //+------------------------------------------------------------------+ bool CIndAC::SupportProperty(ENUM_INDICATOR_PROP_DOUBLE property) { return true; } //+------------------------------------------------------------------+ //| Выводит в журнал краткое описание объекта-индикатора | //+------------------------------------------------------------------+ void CIndAC::PrintShort(void) { ::Print(GetStatusDescription()," ",this.Name()," ",this.Symbol()," ",TimeframeDescription(this.Timeframe())); } //+------------------------------------------------------------------+
Таких классов нам нужно будет сделать в общей сложности 38 штук — по количеству стандартных индикаторов (пользовательский индикатор пока не делаем, так как его реализация будет немного отличаться).
Все эти классы будут иметь одинаковые методы, и отличаться будут только параметрами, передаваемыми в родительский класс из своего конструктора:
//--- Конструктор CIndAC(const string symbol,const ENUM_TIMEFRAMES timeframe,MqlParam &mql_param[]) : CIndicatorDE(IND_AC,symbol,timeframe, INDICATOR_STATUS_STANDART, INDICATOR_GROUP_OSCILLATOR, "Accelerator Oscillator", "AC("+symbol+","+TimeframeDescription(timeframe)+")",mql_param) {}
Во входных параметрах класса мы передаём наименование символа, таймфрейма и уже заполненную структуру параметров индикатора (в данном примере — Accelerator Oscillator).
В списке инициализации передаём в закрытый параметрический конструктор родительского класса (по порядку):
- тип индикатора — IND_AC, наименование символа, таймфрейм
- статус индикатора — стандартный
- группа индикатора — осцилляторы
- наименование индикатора — Accelerator Oscillator
- короткое имя индикатора — AC(символ, таймфрейм) и заполненная структура параметров индикатора
Все остальные методы уже нам знакомы по предыдущим создаваемым нами объектам библиотеки, и выполняют точно такие же задачи.
Методы, возвращающие флаг поддержания объектом целочисленных и вещественных свойств, возвращают true — все свойства поддерживаются объектами-индикаторами.
Метод, возвращающий краткое описание индикатора возвращает строку такого типа:
Standard indicator Accelerator Oscillator EURUSD H4
Во всех остальных файлах подобных классов объектов-индикаторов отличие будет только в конструкторе класса — будут передаваться соответствующие индикатору параметры в конструктор родительского класса.
Например, для индикатора Accumulation/Distribution конструктор класса будет выглядеть так:
//--- Конструктор CIndAD(const string symbol,const ENUM_TIMEFRAMES timeframe,MqlParam &mql_param[]) : CIndicatorDE(IND_AD,symbol,timeframe, INDICATOR_STATUS_STANDART, INDICATOR_GROUP_VOLUMES, "Accumulation/Distribution", "AD("+symbol+","+TimeframeDescription(timeframe)+")",mql_param) {}
Как видим, здесь уже передаются параметры, соответствующие стандартному индикатору AD:
- тип индикатора — IND_AD, наименование символа, таймфрейм
- статус индикатора — стандартный
- группа индикатора — объёмы
- наименование индикатора — Accumulation/Distribution
- короткое имя индикатора — AD(символ,таймфрейм) и заполненная структура параметров индикатора
Все файлы классов-наследников базового класса абстрактного индикатора уже реализованы, и их можно посмотреть самостоятельно в прилагаемых к статье файлах в папке \MQL5\Include\DoEasy\Objects\Indicators\Standart.
Коллекция объектов индикаторов
В соответствии с общей концепцией построения и хранения объектов библиотеки, нам теперь необходимо все создаваемые объекты индикаторов помещать в список-коллекцию. Из этого списка мы всегда сможем получить указатель на нужный нам индикатор по указанным свойствам, или список индикаторов, у которых есть общие одинаковые свойства. По полученному указателю на индикатор мы уже сможем брать все данные, возвращаемые индикатором для дальнейших расчётов.
В папке \MQL5\Include\DoEasy\Collections\ создадим новый класс в файле с именем IndicatorsCollection.mqh.
Помимо стандартных для библиотеки методов, возвращающих требуемые списки объектов из коллекции, класс будет содержать один приватный метод для создания объекта-индикатора и множество методов для создания конкретных объектов-индикаторов в соответствии с их типом, а также множество методов для получения указателей на созданные объекты-индикаторы тоже по их типам. Все методы каждой группы по своей логике идентичны друг другу, поэтому мы рассмотрим только некоторые из них в качестве примеров.
Для того, чтобы класс-коллекция индикаторов имел доступ к классам индикаторов, созданным нами выше, нам нужно подключить их к листингу файла:
//+------------------------------------------------------------------+ //| IndicatorsCollection.mqh | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/ru/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/ru/users/artmedia70" #property version "1.00" //+------------------------------------------------------------------+ //| Включаемые файлы | //+------------------------------------------------------------------+ #include "ListObj.mqh" #include "..\Objects\Indicators\Standart\IndAC.mqh" #include "..\Objects\Indicators\Standart\IndAD.mqh" #include "..\Objects\Indicators\Standart\IndADX.mqh" #include "..\Objects\Indicators\Standart\IndADXW.mqh" #include "..\Objects\Indicators\Standart\IndAlligator.mqh" #include "..\Objects\Indicators\Standart\IndAMA.mqh" #include "..\Objects\Indicators\Standart\IndAO.mqh" #include "..\Objects\Indicators\Standart\IndATR.mqh" #include "..\Objects\Indicators\Standart\IndBands.mqh" #include "..\Objects\Indicators\Standart\IndBears.mqh" #include "..\Objects\Indicators\Standart\IndBulls.mqh" #include "..\Objects\Indicators\Standart\IndBWMFI.mqh" #include "..\Objects\Indicators\Standart\IndCCI.mqh" #include "..\Objects\Indicators\Standart\IndChaikin.mqh" #include "..\Objects\Indicators\Standart\IndDEMA.mqh" #include "..\Objects\Indicators\Standart\IndDeMarker.mqh" #include "..\Objects\Indicators\Standart\IndEnvelopes.mqh" #include "..\Objects\Indicators\Standart\IndForce.mqh" #include "..\Objects\Indicators\Standart\IndFractals.mqh" #include "..\Objects\Indicators\Standart\IndFRAMA.mqh" #include "..\Objects\Indicators\Standart\IndGator.mqh" #include "..\Objects\Indicators\Standart\IndIchimoku.mqh" #include "..\Objects\Indicators\Standart\IndMA.mqh" #include "..\Objects\Indicators\Standart\IndMACD.mqh" #include "..\Objects\Indicators\Standart\IndMFI.mqh" #include "..\Objects\Indicators\Standart\IndMomentum.mqh" #include "..\Objects\Indicators\Standart\IndOBV.mqh" #include "..\Objects\Indicators\Standart\IndOsMA.mqh" #include "..\Objects\Indicators\Standart\IndRSI.mqh" #include "..\Objects\Indicators\Standart\IndRVI.mqh" #include "..\Objects\Indicators\Standart\IndSAR.mqh" #include "..\Objects\Indicators\Standart\IndStDev.mqh" #include "..\Objects\Indicators\Standart\IndStoch.mqh" #include "..\Objects\Indicators\Standart\IndTEMA.mqh" #include "..\Objects\Indicators\Standart\IndTRIX.mqh" #include "..\Objects\Indicators\Standart\IndVIDYA.mqh" #include "..\Objects\Indicators\Standart\IndVolumes.mqh" #include "..\Objects\Indicators\Standart\IndWPR.mqh" //+------------------------------------------------------------------+
Далее посмотрим полный листинг тела класса, а затем разберём по два метода каждой из групп.
//+------------------------------------------------------------------+ //| Коллекция индикаторов | //+------------------------------------------------------------------+ class CIndicatorsCollection : public CObject { private: CListObj m_list; // Список объектов-индикаторов MqlParam m_mql_param[]; // Массив параметров индикатора //--- Создаёт новый объект-индикатор CIndicatorDE *CreateIndicator(const ENUM_INDICATOR ind_type,MqlParam &mql_param[],const string symbol_name=NULL,const ENUM_TIMEFRAMES period=PERIOD_CURRENT); public: //--- Возвращает (1) себя, (2) список индикаторов, (3) список индикаторов по типу CIndicatorsCollection *GetObject(void) { return &this; } CArrayObj *GetList(void) { return &this.m_list; } //--- Возвращает список индикаторов по (1) статусу, (2) типу, (3) таймфрейму, (4) группе, (5) символу, (6) имени, (7) короткому имени CArrayObj *GetListIndByStatus(const ENUM_INDICATOR_STATUS status) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_STATUS,status,EQUAL); } CArrayObj *GetListIndByType(const ENUM_INDICATOR type) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_TYPE,type,EQUAL); } CArrayObj *GetListIndByTimeframe(const ENUM_TIMEFRAMES timeframe) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_TIMEFRAME,timeframe,EQUAL); } CArrayObj *GetListIndByGroup(const ENUM_INDICATOR_GROUP group) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_GROUP,group,EQUAL); } CArrayObj *GetListIndBySymbol(const string symbol) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_SYMBOL,symbol,EQUAL); } CArrayObj *GetListIndByName(const string name) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_NAME,name,EQUAL); } CArrayObj *GetListIndByShortname(const string shortname) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_SHORTNAME,shortname,EQUAL); } //--- Возвращает список объектов-индикаторов по типу индикатора, символу и таймфрейму CArrayObj *GetListAC(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListAD(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListADX(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListADXWilder(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListAlligator(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListAMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListAO(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListATR(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListBands(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListBearsPower(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListBullsPower(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListChaikin(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListCCI(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListDEMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListDeMarker(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListEnvelopes(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListForce(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListFractals(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListFrAMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListGator(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListIchimoku(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListBWMFI(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListMomentum(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListMFI(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListOsMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListMACD(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListOBV(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListSAR(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListRSI(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListRVI(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListStdDev(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListStochastic(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListTEMA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListTriX(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListWPR(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListVIDYA(const string symbol,const ENUM_TIMEFRAMES timeframe); CArrayObj *GetListVolumes(const string symbol,const ENUM_TIMEFRAMES timeframe); //--- Возвращает указатель на объект-индикатор в коллекции по типу индикатора и его параметрам CIndicatorDE *GetIndAC(const string symbol,const ENUM_TIMEFRAMES timeframe); CIndicatorDE *GetIndAD(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndADX(const string symbol,const ENUM_TIMEFRAMES timeframe,const int adx_period); CIndicatorDE *GetIndADXWilder(const string symbol,const ENUM_TIMEFRAMES timeframe,const int adx_period); CIndicatorDE *GetIndAlligator(const string symbol,const ENUM_TIMEFRAMES timeframe, const int jaw_period, const int jaw_shift, const int teeth_period, const int teeth_shift, const int lips_period, const int lips_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndAMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ama_period, const int fast_ema_period, const int slow_ema_period, const int ama_shift, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndAO(const string symbol,const ENUM_TIMEFRAMES timeframe); CIndicatorDE *GetIndATR(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); CIndicatorDE *GetIndBands(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const double deviation, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndBearsPower(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); CIndicatorDE *GetIndBullsPower(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); CIndicatorDE *GetIndChaikin(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ma_period, const int slow_ma_period, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndCCI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndDEMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndDeMarker(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); CIndicatorDE *GetIndEnvelopes(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price, const double deviation); CIndicatorDE *GetIndForce(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndFractals(const string symbol,const ENUM_TIMEFRAMES timeframe); CIndicatorDE *GetIndFrAMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndGator(const string symbol,const ENUM_TIMEFRAMES timeframe, const int jaw_period, const int jaw_shift, const int teeth_period, const int teeth_shift, const int lips_period, const int lips_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndIchimoku(const string symbol,const ENUM_TIMEFRAMES timeframe, const int tenkan_sen, const int kijun_sen, const int senkou_span_b); CIndicatorDE *GetIndBWMFI(const string symbol,const ENUM_TIMEFRAMES timeframe, const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndMomentum(const string symbol,const ENUM_TIMEFRAMES timeframe, const int mom_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndMFI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndOsMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ema_period, const int slow_ema_period, const int signal_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndMACD(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ema_period, const int slow_ema_period, const int signal_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndOBV(const string symbol,const ENUM_TIMEFRAMES timeframe, const ENUM_APPLIED_VOLUME applied_volume); CIndicatorDE *GetIndSAR(const string symbol,const ENUM_TIMEFRAMES timeframe, const double step, const double maximum); CIndicatorDE *GetIndRSI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndRVI(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); CIndicatorDE *GetIndStdDev(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndStochastic(const string symbol,const ENUM_TIMEFRAMES timeframe, const int Kperiod, const int Dperiod, const int slowing, const ENUM_MA_METHOD ma_method, const ENUM_STO_PRICE price_field); CIndicatorDE *GetIndTEMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndTriX(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndWPR(const string symbol,const ENUM_TIMEFRAMES timeframe,const int calc_period); CIndicatorDE *GetIndVIDYA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int cmo_period, const int ema_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); CIndicatorDE *GetIndVolumes(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume); //--- Создаёт новый объект-индикатор по типу индикатора и помещает его в список-коллекцию int CreateAC(const string symbol,const ENUM_TIMEFRAMES timeframe); int CreateAD(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume); int CreateADX(const string symbol,const ENUM_TIMEFRAMES timeframe,const int adx_period); int CreateADXWilder(const string symbol,const ENUM_TIMEFRAMES timeframe,const int adx_period); int CreateAlligator(const string symbol,const ENUM_TIMEFRAMES timeframe, const int jaw_period, const int jaw_shift, const int teeth_period, const int teeth_shift, const int lips_period, const int lips_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); int CreateAMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ama_period, const int fast_ema_period, const int slow_ema_period, const int ama_shift, const ENUM_APPLIED_PRICE applied_price); int CreateAO(const string symbol,const ENUM_TIMEFRAMES timeframe); int CreateATR(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); int CreateBands(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const double deviation, const ENUM_APPLIED_PRICE applied_price); int CreateBearsPower(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); int CreateBullsPower(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); int CreateChaikin(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ma_period, const int slow_ma_period, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_VOLUME applied_volume); int CreateCCI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); int CreateDEMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); int CreateDeMarker(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); int CreateEnvelopes(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price, const double deviation); int CreateForce(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_VOLUME applied_volume); int CreateFractals(const string symbol,const ENUM_TIMEFRAMES timeframe); int CreateFrAMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); int CreateGator(const string symbol,const ENUM_TIMEFRAMES timeframe, const int jaw_period, const int jaw_shift, const int teeth_period, const int teeth_shift, const int lips_period, const int lips_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); int CreateIchimoku(const string symbol,const ENUM_TIMEFRAMES timeframe, const int tenkan_sen, const int kijun_sen, const int senkou_span_b); int CreateBWMFI(const string symbol,const ENUM_TIMEFRAMES timeframe, const ENUM_APPLIED_VOLUME applied_volume); int CreateMomentum(const string symbol,const ENUM_TIMEFRAMES timeframe, const int mom_period, const ENUM_APPLIED_PRICE applied_price); int CreateMFI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_VOLUME applied_volume); int CreateMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); int CreateOsMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ema_period, const int slow_ema_period, const int signal_period, const ENUM_APPLIED_PRICE applied_price); int CreateMACD(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ema_period, const int slow_ema_period, const int signal_period, const ENUM_APPLIED_PRICE applied_price); int CreateOBV(const string symbol,const ENUM_TIMEFRAMES timeframe, const ENUM_APPLIED_VOLUME applied_volume); int CreateSAR(const string symbol,const ENUM_TIMEFRAMES timeframe, const double step, const double maximum); int CreateRSI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); int CreateRVI(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period); int CreateStdDev(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price); int CreateStochastic(const string symbol,const ENUM_TIMEFRAMES timeframe, const int Kperiod, const int Dperiod, const int slowing, const ENUM_MA_METHOD ma_method, const ENUM_STO_PRICE price_field); int CreateTEMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); int CreateTriX(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, const ENUM_APPLIED_PRICE applied_price); int CreateWPR(const string symbol,const ENUM_TIMEFRAMES timeframe,const int calc_period); int CreateVIDYA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int cmo_period, const int ema_period, const int ma_shift, const ENUM_APPLIED_PRICE applied_price); int CreateVolumes(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume); //--- Конструктор CIndicatorsCollection(); }; //+------------------------------------------------------------------+
Листинг кажется внушительным, но на самом деле тут лишь несколько групп однотипных методов, отличающихся друг от друга по типу требуемого индикатора.
Методы, возвращающие списки с нужными типами индикаторов, стандартны для библиотеки, и много раз нами рассматривались:
//--- Возвращает (1) себя, (2) список индикаторов, (3) список индикаторов по типу CIndicatorsCollection *GetObject(void) { return &this; } CArrayObj *GetList(void) { return &this.m_list; } //--- Возвращает список индикаторов по (1) статусу, (2) типу, (3) таймфрейму, (4) группе, (5) символу, (6) имени, (7) короткому имени CArrayObj *GetListIndByStatus(const ENUM_INDICATOR_STATUS status) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_STATUS,status,EQUAL); } CArrayObj *GetListIndByType(const ENUM_INDICATOR type) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_TYPE,type,EQUAL); } CArrayObj *GetListIndByTimeframe(const ENUM_TIMEFRAMES timeframe) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_TIMEFRAME,timeframe,EQUAL); } CArrayObj *GetListIndByGroup(const ENUM_INDICATOR_GROUP group) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_GROUP,group,EQUAL); } CArrayObj *GetListIndBySymbol(const string symbol) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_SYMBOL,symbol,EQUAL); } CArrayObj *GetListIndByName(const string name) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_NAME,name,EQUAL); } CArrayObj *GetListIndByShortname(const string shortname) { return CSelect::ByIndicatorProperty(this.GetList(),INDICATOR_PROP_SHORTNAME,shortname,EQUAL); }
В конструкторе класса обнуляем массив структур параметров индикатора, очищаем список-коллекцию, задаём списку флаг сортированного списка и присваиваем ему идентификатор коллекции индикаторов:
//+------------------------------------------------------------------+ //| Конструктор | //+------------------------------------------------------------------+ CIndicatorsCollection::CIndicatorsCollection() { ::ArrayResize(this.m_mql_param,0); this.m_list.Clear(); this.m_list.Sort(); this.m_list.Type(COLLECTION_INDICATORS_ID); } //+------------------------------------------------------------------+
Приватный метод для создания объекта-индикатора просто создаёт новый объект-индикатор в зависимости от переданного в метод типа создаваемого индикатора и возвращает указатель на созданный объект:
//+------------------------------------------------------------------+ //| Создаёт новый объект-индикатор | //+------------------------------------------------------------------+ CIndicatorDE *CIndicatorsCollection::CreateIndicator(const ENUM_INDICATOR ind_type,MqlParam &mql_param[],const string symbol_name=NULL,const ENUM_TIMEFRAMES period=PERIOD_CURRENT) { string symbol=(symbol_name==NULL || symbol_name=="" ? ::Symbol() : symbol_name); ENUM_TIMEFRAMES timeframe=(period==PERIOD_CURRENT ? ::Period() : period); CIndicatorDE *indicator=NULL; switch(ind_type) { case IND_AC : indicator=new CIndAC(symbol,timeframe,mql_param); break; case IND_AD : indicator=new CIndAD(symbol,timeframe,mql_param); break; case IND_ADX : indicator=new CIndADX(symbol,timeframe,mql_param); break; case IND_ADXW : indicator=new CIndADXW(symbol,timeframe,mql_param); break; case IND_ALLIGATOR : indicator=new CIndAlligator(symbol,timeframe,mql_param); break; case IND_AMA : indicator=new CIndAMA(symbol,timeframe,mql_param); break; case IND_AO : indicator=new CIndAO(symbol,timeframe,mql_param); break; case IND_ATR : indicator=new CIndATR(symbol,timeframe,mql_param); break; case IND_BANDS : indicator=new CIndBands(symbol,timeframe,mql_param); break; case IND_BEARS : indicator=new CIndBears(symbol,timeframe,mql_param); break; case IND_BULLS : indicator=new CIndBulls(symbol,timeframe,mql_param); break; case IND_BWMFI : indicator=new CIndBWMFI(symbol,timeframe,mql_param); break; case IND_CCI : indicator=new CIndCCI(symbol,timeframe,mql_param); break; case IND_CHAIKIN : indicator=new CIndCHO(symbol,timeframe,mql_param); break; case IND_DEMA : indicator=new CIndDEMA(symbol,timeframe,mql_param); break; case IND_DEMARKER : indicator=new CIndDeMarker(symbol,timeframe,mql_param); break; case IND_ENVELOPES : indicator=new CIndEnvelopes(symbol,timeframe,mql_param); break; case IND_FORCE : indicator=new CIndForce(symbol,timeframe,mql_param); break; case IND_FRACTALS : indicator=new CIndFractals(symbol,timeframe,mql_param); break; case IND_FRAMA : indicator=new CIndFRAMA(symbol,timeframe,mql_param); break; case IND_GATOR : indicator=new CIndGator(symbol,timeframe,mql_param); break; case IND_ICHIMOKU : indicator=new CIndIchimoku(symbol,timeframe,mql_param); break; case IND_MA : indicator=new CIndMA(symbol,timeframe,mql_param); break; case IND_MACD : indicator=new CIndMACD(symbol,timeframe,mql_param); break; case IND_MFI : indicator=new CIndMFI(symbol,timeframe,mql_param); break; case IND_MOMENTUM : indicator=new CIndMomentum(symbol,timeframe,mql_param); break; case IND_OBV : indicator=new CIndOBV(symbol,timeframe,mql_param); break; case IND_OSMA : indicator=new CIndOsMA(symbol,timeframe,mql_param); break; case IND_RSI : indicator=new CIndRSI(symbol,timeframe,mql_param); break; case IND_RVI : indicator=new CIndRVI(symbol,timeframe,mql_param); break; case IND_SAR : indicator=new CIndSAR(symbol,timeframe,mql_param); break; case IND_STDDEV : indicator=new CIndStDev(symbol,timeframe,mql_param); break; case IND_STOCHASTIC : indicator=new CIndStoch(symbol,timeframe,mql_param); break; case IND_TEMA : indicator=new CIndTEMA(symbol,timeframe,mql_param); break; case IND_TRIX : indicator=new CIndTRIX(symbol,timeframe,mql_param); break; case IND_VIDYA : indicator=new CIndVIDYA(symbol,timeframe,mql_param); break; case IND_VOLUMES : indicator=new CIndVolumes(symbol,timeframe,mql_param); break; case IND_WPR : indicator=new CIndWPR(symbol,timeframe,mql_param); break; case IND_CUSTOM : break; default: break; } return indicator; } //+------------------------------------------------------------------+
По умолчанию, а также временно и для пользовательского индикатора (его создание будет реализовано в последующих статьях) метод возвращает NULL.
Метод, создающий объект-индикатор Accelerator Oscillator:
//+------------------------------------------------------------------+ //| Создаёт новый объект-индикатор Accelerator Oscillator | //| и помещает его в список-коллекцию | //+------------------------------------------------------------------+ int CIndicatorsCollection::CreateAC(const string symbol,const ENUM_TIMEFRAMES timeframe) { //--- У индикатора AC нет параметров - обнуляем размер массива структур параметров ::ArrayResize(this.m_mql_param,0); //--- Создаём объект-индикатор CIndicatorDE *indicator=this.CreateIndicator(IND_AC,this.m_mql_param,symbol,timeframe); if(indicator==NULL) return INVALID_HANDLE; int index=this.m_list.Search(indicator); //--- Если такой индикатор уже есть в списке if(index!=WRONG_VALUE) { //--- Получаем объект-индикатор из списка и возвращаем хэндл индикатора indicator=this.m_list.At(index); return indicator.Handle(); } //--- Если такого индикатора нет в списке else { //--- Если не удалось добавить объект-индикатор в список //--- выводим об этом сообщение и возвращаем INVALID_HANDLE if(!this.m_list.Add(indicator)) { Print(CMessage::Text(MSG_LIB_SYS_FAILED_ADD_IND_TO_LIST)); return INVALID_HANDLE; } //--- Возвращаем хэндл добавленного в список нового индикатора return indicator.Handle(); } //--- Возвращаем INVALID_HANDLE return INVALID_HANDLE; } //+------------------------------------------------------------------+
Логика метода описана в его листинге, и думаю, вопросов не должна вызывать. Отметим, что объект-индикатор создаётся в методе его создания CreateIndicator(), рассмотренного нами выше. В метод передаётся тип индикатора IND_AC. Так как у индикатора AC нет никаких входных параметров, то и массив структур параметров индикатора здесь не нужен. Поэтому массив обнуляется, что указывает на ненужность его использования при создании индикатора в классе CIndicatorDE, рассмотренного нами в прошлой статье.
Остальные методы создания других стандартных индикаторов по своей логике идентичны только что рассмотренному и отличаются лишь указанием нужного индикатора и заполнением массива структур параметров индикатора там, где это требуется.
Для примера рассмотрим метод создания индикатора Alligator, где требуются восемь входных параметров, и все они записываются в массив параметров индикатора в соответствии с порядком следования этих параметров у индикатора Alligator и в метод создания объекта-индикатора передаётся тип IND_ALLIGATOR:
//+------------------------------------------------------------------+ //| Создаёт новый объект-индикатор Alligator | //| и помещает его в список-коллекцию | //+------------------------------------------------------------------+ int CIndicatorsCollection::CreateAlligator(const string symbol,const ENUM_TIMEFRAMES timeframe, const int jaw_period, const int jaw_shift, const int teeth_period, const int teeth_shift, const int lips_period, const int lips_shift, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price) { //--- Записываем в массив структур параметров необходимые параметры индикатора ::ArrayResize(this.m_mql_param,8); this.m_mql_param[0].type=TYPE_INT; this.m_mql_param[0].integer_value=jaw_period; this.m_mql_param[1].type=TYPE_INT; this.m_mql_param[1].integer_value=jaw_shift; this.m_mql_param[2].type=TYPE_INT; this.m_mql_param[2].integer_value=teeth_period; this.m_mql_param[3].type=TYPE_INT; this.m_mql_param[3].integer_value=teeth_shift; this.m_mql_param[4].type=TYPE_INT; this.m_mql_param[4].integer_value=lips_period; this.m_mql_param[5].type=TYPE_INT; this.m_mql_param[5].integer_value=lips_shift; this.m_mql_param[6].type=TYPE_INT; this.m_mql_param[6].integer_value=ma_method; this.m_mql_param[7].type=TYPE_INT; this.m_mql_param[7].integer_value=applied_price; //--- Создаём объект-индикатор CIndicatorDE *indicator=this.CreateIndicator(IND_ALLIGATOR,this.m_mql_param,symbol,timeframe); if(indicator==NULL) return INVALID_HANDLE; int index=this.m_list.Search(indicator); //--- Если такой индикатор уже есть в списке if(index!=WRONG_VALUE) { //--- Получаем объект-индикатор из списка и возвращаем хэндл индикатора indicator=this.m_list.At(index); return indicator.Handle(); } //--- Если такого индикатора нет в списке else { //--- Если не удалось добавить объект-индикатор в список //--- выводим об этом сообщение и возвращаем INVALID_HANDLE if(!this.m_list.Add(indicator)) { Print(CMessage::Text(MSG_LIB_SYS_FAILED_ADD_IND_TO_LIST)); return INVALID_HANDLE; } //--- Возвращаем хэндл добавленного в список нового индикатора return indicator.Handle(); } //--- Возвращаем INVALID_HANDLE return INVALID_HANDLE; } //+------------------------------------------------------------------+
Это все отличия каждого метода друг от друга. Остальные методы создания индикаторов рассматривать не будем — они есть в прилагаемых к статье файлах.
Метод, возвращающий список всех объектов-индикаторов Accelerator Oscillator, находящихся в списке-коллекции, по символу и таймфрейму:
//+------------------------------------------------------------------+ //| Возвращает список объектов-индикаторов Accelerator Oscillator | //| по символу и таймфрейму | //+------------------------------------------------------------------+ CArrayObj *CIndicatorsCollection::GetListAC(const string symbol,const ENUM_TIMEFRAMES timeframe) { CArrayObj *list=GetListIndByType(IND_AC); list=CSelect::ByIndicatorProperty(list,INDICATOR_PROP_SYMBOL,symbol,EQUAL); return CSelect::ByIndicatorProperty(list,INDICATOR_PROP_TIMEFRAME,timeframe,EQUAL); } //+------------------------------------------------------------------+
Сначала получаем список всех объектов-индикаторов Accelerator Oscillator, находящихся в списке-коллекции,
затем фильтруем полученный список по символу
и возвращаем полученный список, ещё раз отфильтрованный уже по таймфрейму.
Остальные методы полностью идентичны вышерассмотренному, за исключением того, что сначала получаем список всех нужных индикаторов в соответствии с назначением метода.
Например, для получения списка всех объектов-индикаторов Accumulation/Distribution, находящихся в списке-коллекции, по символу и таймфрейму, метод будет таким:
//+------------------------------------------------------------------+ //| Возвращает список объектов-индикаторов Accumulation/Distribution | //| по символу и таймфрейму | //+------------------------------------------------------------------+ CArrayObj *CIndicatorsCollection::GetListAD(const string symbol,const ENUM_TIMEFRAMES timeframe) { CArrayObj *list=GetListIndByType(IND_AD); list=CSelect::ByIndicatorProperty(list,INDICATOR_PROP_SYMBOL,symbol,EQUAL); return CSelect::ByIndicatorProperty(list,INDICATOR_PROP_TIMEFRAME,timeframe,EQUAL); } //+------------------------------------------------------------------+
Здесь сначала получаем список всех индикаторов AD, находящихся в коллекции, и далее фильтруем список по символу и таймфрейму как и в вышерассмотренном методе.
Метод, возвращающий указатель на объект-индикатор в коллекции по типу индикатора и его параметрам сегодня реализуем только один — для индикатора Accelerator Oscillator:
//+------------------------------------------------------------------+ //| Возвращает указатель на объект-индикатор Accelerator Oscillator | //+------------------------------------------------------------------+ CIndicatorDE *CIndicatorsCollection::GetIndAC(const string symbol,const ENUM_TIMEFRAMES timeframe) { CArrayObj *list=GetListAC(symbol,timeframe); return(list==NULL || list.Total()==0 ? NULL : list.At(0)); } //+------------------------------------------------------------------+
Так как этот индикатор (и некоторые другие) не имеет входных параметров, то при выборе его из списка-коллекции по символу и таймфрейму, в списке будет содержаться только один объект-индикатор (по индексу 0), соответствующий типу IND_AC и запрошенным символу и таймфрейму.
Те же индикаторы, у которых имеются входные параметры, требуют для реализации их поиска по указанным параметрам дополнительных методов поиска по массиву структур параметров индикатора, и это уже выйдет за пределы размера данной статьи. Поэтому такие методы будут рассмотрены в следующей.
Так как данная статья имеет больше обучающий уклон, и не претендует на завершённость, то тестировать мы будем лишь создание одного объекта-индикатора Accelerator Oscillator. В прошлой статье у нас уже был проведён такой тест по созданию объекта-индикатора AC в классе-коллекции буферов:
//+------------------------------------------------------------------+ //| Создаёт мультисимвольный мультипериодный AC | //+------------------------------------------------------------------+ int CBuffersCollection::CreateAC(const string symbol,const ENUM_TIMEFRAMES timeframe,const int id=WRONG_VALUE) { //--- Для проверки создаём объёкт-индикатор, выводим его данные и сразу удаляем ::ArrayResize(this.m_mql_param,0); CIndicatorDE *indicator=new CIndicatorDE(IND_AC,symbol,timeframe,INDICATOR_STATUS_STANDART,INDICATOR_GROUP_OSCILLATOR,"Accelerator Oscillator","AC("+symbol+","+TimeframeDescription(timeframe)+")",this.m_mql_param); indicator.Print(); delete indicator; //--- Создаём хэндл индикатора и устанавливаем идентификатор по умолчанию
Cегодня мы сделаем точно так же — в этом же методе создадим объект индикатора Accelerator Oscillator, но уже при помощи вновь написанных классов.
Забегая наперёд скажу: нам необходимо будет "видеть" список-коллекцию в классе коллекции таймсерий для того, чтобы нам открылась возможность хранения данных всех создаваемых индикаторов в объектах-барах, которые "лежат" в списках таймсерий.
Поэтому предварительно нам нужно подключить к классу коллекции таймсерий класс-коллекцию индикаторов в файле \MQL5\Include\DoEasy\Collections\TimeSeriesCollection.mqh:
//+------------------------------------------------------------------+ //| TimeSeriesCollection.mqh | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/ru/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/ru/users/artmedia70" #property version "1.00" //+------------------------------------------------------------------+ //| Включаемые файлы | //+------------------------------------------------------------------+ #include "ListObj.mqh" #include "..\Objects\Series\TimeSeriesDE.mqh" #include "..\Objects\Symbols\Symbol.mqh" #include "IndicatorsCollection.mqh" //+------------------------------------------------------------------+
Далее в приватной секции класса объявим указатель на класс-коллекцию индикаторов:
//+------------------------------------------------------------------+ //| Коллекция таймсерий символов | //+------------------------------------------------------------------+ class CTimeSeriesCollection : public CBaseObjExt { private: CListObj m_list; // Список используемых таймсерий символов CIndicatorsCollection *m_indicators; // Указатель на объект-коллекцию индикаторов //--- Возвращает индекс таймсерии по имени символа int IndexTimeSeries(const string symbol); public:
И в конце листинга класса создадим метод инициализации, через который будем передавать в класс указатель на объект коллекции индикаторов в главном объекте библиотеки CEngine:
//--- Конструктор CTimeSeriesCollection(); //--- Получение указателей на коллекцию индикаторов (метод вызывается в методе CollectionOnInit() объекта CEngine) void OnInit(CIndicatorsCollection *indicators) { this.m_indicators=indicators; } }; //+------------------------------------------------------------------+
В файле класса-коллекции буферов \MQL5\Include\DoEasy\Collections\BuffersCollection.mqh так же объявим указатель на объект коллекции индикаторов:
//+------------------------------------------------------------------+ //| Коллекция индикаторных буферов | //+------------------------------------------------------------------+ class CBuffersCollection : public CObject { private: CListObj m_list; // Список объектов-буферов CTimeSeriesCollection *m_timeseries; // Указатель на объект-коллекцию таймсерий CIndicatorsCollection *m_indicators; // Указатель на объект-коллекцию индикаторов MqlParam m_mql_param[]; // Массив параметров индикатора //--- Возвращает индекс (1) последнего, (2) следующего рисуемого, (3) базового буфера int GetIndexLastPlot(void); int GetIndexNextPlot(void); int GetIndexNextBase(void); //--- Создаёт новый объект-буфер и помещает его в список-коллекцию bool CreateBuffer(ENUM_BUFFER_STATUS status); //--- Получает данные нужных таймсерий и баров для работы с одним баром буфера, возвращает количество баров int GetBarsData(CBuffer *buffer,const int series_index,int &index_bar_period); public:
В метод класса OnInit() допишем присвоение этому указателю значения, передаваемого входным параметром:
//--- Конструктор CBuffersCollection(); //--- Получение указателей на коллекции таймсерий и индикаторов (метод вызывается в методе CollectionOnInit() объекта CEngine) void OnInit(CTimeSeriesCollection *timeseries,CIndicatorsCollection *indicators) { this.m_timeseries=timeseries; this.m_indicators=indicators; } }; //+------------------------------------------------------------------+
И в методе создания индикатора AC изменим создание объекта-индикатора, сделанное нами в прошлой статье на его создание и получение при помощи класса-коллекции индикаторов:
//+------------------------------------------------------------------+ //| Создаёт мультисимвольный мультипериодный AC | //+------------------------------------------------------------------+ int CBuffersCollection::CreateAC(const string symbol,const ENUM_TIMEFRAMES timeframe,const int id=WRONG_VALUE) { //--- Для проверки создаём объёкт-индикатор, выводим его данные и сразу удаляем //--- Параметры не нужны для AC, поэтому обнуляем массив структур параметров индикатора ::ArrayResize(this.m_mql_param,0); //--- Создаём индикатор AC и добавляем его в коллекцию this.m_indicators.CreateAC(symbol,timeframe); //--- Получаем из коллекции объект-индикатора AC CIndicatorDE *indicator=this.m_indicators.GetIndAC(symbol,timeframe); //--- Выводим в журнал все данные созданного индикатора, выводим его краткое описание и удаляем объект-индикатор indicator.Print(); indicator.PrintShort(); delete indicator; //--- Создаём хэндл индикатора и устанавливаем идентификатор по умолчанию
Теперь доработаем класс главного объекта библиотеки CEngine.
В файле \MQL5\Include\DoEasy\Engine.mqh пропишем подключение к листингу класса файла коллекции индикаторов:
//+------------------------------------------------------------------+ //| Engine.mqh | //| Copyright 2020, MetaQuotes Software Corp. | //| https://mql5.com/ru/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2020, MetaQuotes Software Corp." #property link "https://mql5.com/ru/users/artmedia70" #property version "1.00" //+------------------------------------------------------------------+ //| Включаемые файлы | //+------------------------------------------------------------------+ #include "Services\TimerCounter.mqh" #include "Collections\HistoryCollection.mqh" #include "Collections\MarketCollection.mqh" #include "Collections\EventsCollection.mqh" #include "Collections\AccountsCollection.mqh" #include "Collections\SymbolsCollection.mqh" #include "Collections\ResourceCollection.mqh" #include "Collections\TimeSeriesCollection.mqh" #include "Collections\BuffersCollection.mqh" #include "Collections\IndicatorsCollection.mqh" #include "TradingControl.mqh" //+------------------------------------------------------------------+
В приватной секции класса объявим объект класса-коллекции индикаторов:
//+------------------------------------------------------------------+ //| Класс-основа библиотеки | //+------------------------------------------------------------------+ class CEngine { private: CHistoryCollection m_history; // Коллекция исторических ордеров и сделок CMarketCollection m_market; // Коллекция рыночных ордеров и сделок CEventsCollection m_events; // Коллекция событий CAccountsCollection m_accounts; // Коллекция аккаунтов CSymbolsCollection m_symbols; // Коллекция символов CTimeSeriesCollection m_time_series; // Коллекция таймсерий CBuffersCollection m_buffers; // Коллекция индикаторных буферов CIndicatorsCollection m_indicators; // Коллекция индикаторов CResourceCollection m_resource; // Список ресурсов CTradingControl m_trading; // Объект управления торговлей CPause m_pause; // Объект "Пауза" CArrayObj m_list_counters; // Список счётчиков таймера int m_global_error; // Код глобальной ошибки bool m_first_start; // Флаг первого запуска bool m_is_hedge; // Флаг хедж-счёта bool m_is_tester; // Флаг работы в тестере bool m_is_market_trade_event; // Флаг торгового события на счёте bool m_is_history_trade_event; // Флаг торгового события в истории счёта bool m_is_account_event; // Флаг события изменения аккаунта bool m_is_symbol_event; // Флаг события изменения свойств символа ENUM_TRADE_EVENT m_last_trade_event; // Последнее торговое событие на счёте int m_last_account_event; // Последнее событие в свойствах счёта int m_last_symbol_event; // Последнее событие в свойствах символа ENUM_PROGRAM_TYPE m_program; // Тип программы string m_name; // Имя программы //--- Возвращает индекс счётчика по id int CounterIndex(const int id) const; //--- Возвращает флаг первого запуска bool IsFirstStart(void); //--- Работа с событиями (1) ордеров, сделок и позиций, (2) аккаунтов void TradeEventsControl(void); void AccountEventsControl(void); //--- (1) Работа с коллекцией символов и (2) событиями списка символов в окне обзора рынка void SymbolEventsControl(void); void MarketWatchEventsControl(void); //--- Возвращает последний (1) рыночный отложенный ордер, (2) маркет-ордер, (3) последнюю позицию, (4) позицию по тикету COrder *GetLastMarketPending(void); COrder *GetLastMarketOrder(void); COrder *GetLastPosition(void); COrder *GetPosition(const ulong ticket); //--- Возвращает последний (1) удалённый отложенный ордер, (2) исторический маркет-ордер, (3) исторический ордер (маркет или отложенный) по его тикету COrder *GetLastHistoryPending(void); COrder *GetLastHistoryOrder(void); COrder *GetHistoryOrder(const ulong ticket); //--- Возвращает (1) первый и (2) последний исторический маркет-ордер из списка всех ордеров позиции, (3) последнюю сделку COrder *GetFirstOrderPosition(const ulong position_id); COrder *GetLastOrderPosition(const ulong position_id); COrder *GetLastDeal(void); //--- Извлекает нужное ushort-число из упакованного long-значения ushort LongToUshortFromByte(const long source_value,const uchar index) const; public:
В публичной секции напишем два метода для возврата указателя на объект-коллекции индикаторов и указателя на список индикаторов этой коллекции:
//--- Возвращает индекс бара на графике указанного таймфрейма по индексу бара текущего графика int IndexBarPeriodByBarCurrent(const int series_index,const string symbol,const ENUM_TIMEFRAMES timeframe) { return this.m_time_series.IndexBarPeriodByBarCurrent(series_index,symbol,timeframe); } //--- Возвращает (1) коллекцию индикаторов, (2) список индикаторов из коллекции CIndicatorsCollection *GetIndicatorsCollection(void) { return &this.m_indicators; } CArrayObj *GetListIndicators(void) { return this.m_indicators.GetList(); }
Эти методы нам пригодятся для обращения к коллекции индикаторов из своих программ.
Допишем в метод CollectionOnInit() передачу указателя на коллекцию индикаторов в классы-коллекции буферов и таймсерий:
//--- Передаёт в торговый класс и класс-коллекцию индикаторных буферов указатели на все необходимые коллекции void CollectionOnInit(void) { this.m_trading.OnInit(this.GetAccountCurrent(),m_symbols.GetObject(),m_market.GetObject(),m_history.GetObject(),m_events.GetObject()); this.m_buffers.OnInit(this.m_time_series.GetObject(),this.m_indicators.GetObject()); this.m_time_series.OnInit(this.m_indicators.GetObject()); }
Теперь при инициализации библиотеки во все классы, где требуется доступ к коллекции индикаторов, будет передан указатель на объект коллекции индикаторов, и они смогут работать с этой коллекцией.
На сегодня это все необходимые доработки для создания класса-коллекции индикаторов.
Тестирование
Для тестирования нам потребуется индикатор из прошлой статьи без каких-либо изменений.
Просто сохраним его в новой папке \MQL5\Indicators\TestDoEasy\Part54\ под новым именем TestDoEasyPart54.mq5.
Скомпилируем индикатор и запустим его на графике.
В журнал будут выведены полностью все параметры созданного индикатора Accelerator Oscillator , а затем его краткое описание:
Счёт 8550475: Artyom Trishkin (MetaQuotes Software Corp.) 10425.23 USD, 1:100, Hedge, Демонстрационный счёт MetaTrader 5 --- Инициализация библиотеки "DoEasy" --- Работа только с текущим символом. Количество используемых символов: 1 "EURUSD" Работа с заданным списком таймфреймов: "H4" "H1" Таймсерия символа EURUSD: - Таймсерия "EURUSD" H1: Запрошено: 1000, Фактически: 0, Создано: 0, На сервере: 0 - Таймсерия "EURUSD" H4: Запрошено: 1000, Фактически: 1000, Создано: 1000, На сервере: 6231 Время инициализации библиотеки: 00:00:00.156 ============= Начало списка параметров: "Стандартный индикатор" ============= Статус индикатора: Стандартный индикатор Тип индикатора: AC Таймфрейм индикатора: H4 Хэндл индикатора: 10 Группа индикатора: Осциллятор ------ Пустое значение для построения, для которого нет отрисовки: EMPTY_VALUE ------ Символ индикатора: EURUSD Имя индикатора: "Accelerator Oscillator" Короткое имя индикатора: "AC(EURUSD,H4)" ================== Конец списка параметров: "Стандартный индикатор" ================== Стандартный индикатор Accelerator Oscillator EURUSD H4 Буфер(P0/B0/C1): Гистограмма от нулевой линии EURUSD H4 Буфер[P0/B2/C2]: Расчётный буфер Таймсерия "EURUSD" H1 создана успешно: - Таймсерия "EURUSD" H1: Запрошено: 1000, Фактически: 1000, Создано: 1000, На сервере: 6256
Что дальше
В следующей статье продолжим работу над классом-коллекцией индикаторов.
Ниже прикреплены все файлы текущей версии библиотеки и файл тестового индикатора для MQL5. Их можно скачать и протестировать всё самостоятельно.
Хочу отметить, что класс-коллекция индикаторов на данный момент находится в процессе разработки, поэтому крайне не рекомендуется использовать его для использования в своих программах.
При возникновении вопросов, замечаний и пожеланий, вы можете озвучить их в комментариях к статье.
Статьи этой серии:
Работа с таймсериями в библиотеке DoEasy (Часть 35): Объект "Бар" и список-таймсерия символа
Работа с таймсериями в библиотеке DoEasy (Часть 36): Объект таймсерий всех используемых периодов символа
Работа с таймсериями в библиотеке DoEasy (Часть 37): Коллекция таймсерий - база данных таймсерий по символам и периодам
Работа с таймсериями в библиотеке DoEasy (Часть 38): Коллекция таймсерий - реалтайм обновление и доступ к данным из программы
Работа с таймсериями в библиотеке DoEasy (Часть 39): Индикаторы на основе библиотеки - подготовка данных и события таймсерий
Работа с таймсериями в библиотеке DoEasy (Часть 40): Индикаторы на основе библиотеки - реалтайм обновление данных
Работа с таймсериями в библиотеке DoEasy (Часть 41): Пример мультисимвольного мультипериодного индикатора
Работа с таймсериями в библиотеке DoEasy (Часть 42): Класс объекта абстрактного индикаторного буфера
Работа с таймсериями в библиотеке DoEasy (Часть 43): Классы объектов индикаторных буферов
Работа с таймсериями в библиотеке DoEasy (Часть 44): Класс-коллекция объектов индикаторных буферов
Работа с таймсериями в библиотеке DoEasy (Часть 45): Мультипериодные индикаторные буферы
Работа с таймсериями в библиотеке DoEasy (Часть 46): Мультипериодные, мультисимвольные индикаторные буферы
Работа с таймсериями в библиотеке DoEasy (Часть 47): Мультипериодные мультисимвольные стандартные индикаторы
Работа с таймсериями в библиотеке DoEasy (Часть 48): Мультипериодные мультисимвольные индикаторы на одном буфере в подокне
Работа с таймсериями в библиотеке DoEasy (Часть 49): Мультипериодные мультисимвольные многобуферные стандартные индикаторы
Работа с таймсериями в библиотеке DoEasy (Часть 50): Мультипериодные мультисимвольные стандартные индикаторы со смещением
Работа с таймсериями в библиотеке DoEasy (Часть 51): Составные мультипериодные мультисимвольные стандартные индикаторы
Работа с таймсериями в библиотеке DoEasy (Часть 52): Кроссплатформенность мультипериодных мультисимвольных однобуферных стандартных индикаторов
Работа с таймсериями в библиотеке DoEasy (Часть 53): Класс абстрактного базового индикатора
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Не могли бы вы показать пример?
От статьи 40 и далее
А чё так мало? Надо прямо с первой начинать. Иначе возможны непонимания.
А чё так мало? Надо прямо с первой начинать. Иначе возможны непонимания.
Этот человек досконально изучает всю библиотеку. В отличии от тебя, друг мой :)
От статьи 40 и далее
Может быть, я неправильно понял, но пока я не хочу писать свой собственный индикатор с помощью библиотеки DoEasy (начиная со статьи 40)... Я имел в виду создание объекта индикатора (как показано в статьях 53-55), который загружает существующий индикатор типа IND_CUSTOM, например Indicators/ZigZag.mq4 or Indicators/Examples/ZigZag.mq5; или даже любой индикатор, доступный на https://www.mql5.com/en/code/mt4/indicators or https://www.mql5.com/en/code/mt5/indicators
Может быть, я неправильно понял, но пока я не хочу писать свой собственный индикатор с помощью библиотеки DoEasy (начиная со статьи 40)... Я имел в виду создание объекта индикатора (как показано в статьях 53-55), который загружает существующий индикатор типа IND_CUSTOM, например Indicators/ZigZag.mq4 or Indicators/Examples/ZigZag.mq5; или даже любой индикатор, доступный на https://www.mql5.com/en/code/mt4/indicators or https://www.mql5.com/en/code/mt5/indicators
Понял. Да, будет в следующей статье (№56).