//+------------------------------------------------------------------+ //| IndMSTF.mqh | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" //--- includes #include //--- defines #define TIMER_COUNT_1 (90) // Размер таймера 1. Не должен быть более двух минут (120) #define TIMER_COUNT_2 (20) // Размер таймера 2. Слишком малые значения быстро запускают эмуляцию тика, что не желательно при активном рынке //--- enums enum ENUM_IND_CATEGORY // Категории индикаторов { IND_CATEGORY_NONE, // Не задана IND_CATEGORY_TREND, // Трендовые IND_CATEGORY_OSCILLATOR, // Осцилляторы IND_CATEGORY_VOLUME, // Объемы IND_CATEGORY_WILLIAMS, // Билла Вильямса IND_CATEGORY_CUSTOM, // Пользовательские }; enum ENUM_COMPARE_MODE // Режим сравнения { // По умолчанию режим сравнения имеет нулевое значение, что производит сравнение по всем свойствам COMPARE_MODE_HANDLE=1, // Сравнение по хэндлу COMPARE_MODE_SYMBOL, // Сравнение по символу COMPARE_MODE_TIMEFRAME, // Сравнение по периоду графика COMPARE_MODE_ID, // Сравнение по идентификатору COMPARE_MODE_DESCRIPTION, // Сравнение по пользовательскому описанию COMPARE_MODE_CATEGORY, // Сравнение по категории }; enum ENUM_LINE_STATE // Состояние линии индикатора { LINE_STATE_NONE, // Неопределённое состояние LINE_STATE_UP, // Направление вверх LINE_STATE_DOWN, // Направление вниз LINE_STATE_TURN_UP, // Разворот вверх LINE_STATE_TURN_DOWN, // Разворот вниз LINE_STATE_STOP_UP, // Остановка направления вверх LINE_STATE_STOP_DOWN, // Остановка направления вниз LINE_STATE_ABOVE, // Над значением LINE_STATE_BELOW, // Под значением LINE_STATE_CROSS_UP, // Пересечение значения вверх LINE_STATE_CROSS_DOWN, // Пересечение значения вниз LINE_STATE_TOUCH_BELOW, // Касание значения снизу LINE_STATE_TOUCH_ABOVE, // Касание значения сверху LINE_STATE_EQUALS, // Равно значению }; enum ENUM_ERR_TYPE // Тип ошибки при расчётах индикаторов { ERR_TYPE_NO_ERROR, // Нет ошибки ERR_TYPE_NO_SYNC, // Данные не синхронизированы ERR_TYPE_NO_DATA, // Данные не загружены ERR_TYPE_NO_CALC, // Расчёт не завершён }; //--- struct struct SBuffer // Структура индикаторного буфера { private: double init_value; // Инициализирующее значение uchar init_color_idx; // Инициализирующее значение индекса цвета int shift; // Сдвиг буфера по горизонтали uint source; // Номер буфера исходного индикатора bool colored; // Флаг цветного буфера ENUM_DRAW_TYPE draw_type; // Стиль рисования буфера //--- Изменяет размер всех массивов bool ResizeArrays(const int new_size) { bool res=true; switch(draw_type) { //--- Один буфер case DRAW_LINE : case DRAW_HISTOGRAM : case DRAW_ARROW : case DRAW_SECTION : return ArrayResize(array0,new_size)==new_size; //--- Два буфера case DRAW_HISTOGRAM2 : case DRAW_ZIGZAG : case DRAW_FILLING : res =(ArrayResize(array0,new_size)==new_size); res &=(ArrayResize(array1,new_size)==new_size); return res; //--- Четыре буфера case DRAW_BARS : case DRAW_CANDLES : res =(ArrayResize(array0,new_size)==new_size); res &=(ArrayResize(array1,new_size)==new_size); res &=(ArrayResize(array2,new_size)==new_size); res &=(ArrayResize(array3,new_size)==new_size); return res; //--- Один буфер + буфер цвета case DRAW_COLOR_LINE : case DRAW_COLOR_HISTOGRAM : case DRAW_COLOR_ARROW : case DRAW_COLOR_SECTION : res =(ArrayResize(array0,new_size)==new_size); res &=(ArrayResize(color_indexes,new_size)==new_size); return res; //--- Два буфера + буфер цвета case DRAW_COLOR_HISTOGRAM2 : case DRAW_COLOR_ZIGZAG : res =(ArrayResize(array0,new_size)==new_size); res &=(ArrayResize(array1,new_size)==new_size); res &=(ArrayResize(color_indexes,new_size)==new_size); return res; //--- Четыре буфера + буфер цвета case DRAW_COLOR_BARS : case DRAW_COLOR_CANDLES : res =(ArrayResize(array0,new_size)==new_size); res &=(ArrayResize(array1,new_size)==new_size); res &=(ArrayResize(array2,new_size)==new_size); res &=(ArrayResize(array3,new_size)==new_size); res &=(ArrayResize(color_indexes,new_size)==new_size); return res; //---DRAW_NONE default: break; } return false; } //--- Инициализирует все массивы int InitArrays(void) { bool res=0; switch(draw_type) { //--- Один буфер case DRAW_LINE : case DRAW_HISTOGRAM : case DRAW_ARROW : case DRAW_SECTION : return ArrayInitialize(array0,init_value); //--- Два буфера case DRAW_HISTOGRAM2 : case DRAW_ZIGZAG : case DRAW_FILLING : res+=ArrayInitialize(array0,init_value); res+=ArrayInitialize(array1,init_value); return res/2; //--- Четыре буфера case DRAW_BARS : case DRAW_CANDLES : res+=ArrayInitialize(array0,init_value); res+=ArrayInitialize(array1,init_value); res+=ArrayInitialize(array2,init_value); res+=ArrayInitialize(array3,init_value); return res/4; //--- Один буфер + буфер цвета case DRAW_COLOR_LINE : case DRAW_COLOR_HISTOGRAM : case DRAW_COLOR_ARROW : case DRAW_COLOR_SECTION : res+=ArrayInitialize(array0,init_value); res+=ArrayInitialize(color_indexes,init_color_idx); return res/2; //--- Два буфера + буфер цвета case DRAW_COLOR_HISTOGRAM2 : case DRAW_COLOR_ZIGZAG : res+=ArrayInitialize(array0,init_value); res+=ArrayInitialize(array1,init_value); res+=ArrayInitialize(color_indexes,init_color_idx); return res/3; //--- Четыре буфера + буфер цвета case DRAW_COLOR_BARS : case DRAW_COLOR_CANDLES : res+=ArrayInitialize(array0,init_value); res+=ArrayInitialize(array1,init_value); res+=ArrayInitialize(array2,init_value); res+=ArrayInitialize(array3,init_value); res+=ArrayInitialize(color_indexes,init_color_idx); return res/5; //---DRAW_NONE default: break; } return false; } public: double array0[]; // Массив-буфер0 индикатора double array1[]; // Массив-буфер1 индикатора (2-й массив для расчёта) double array2[]; // Массив-буфер2 индикатора (3-й массив для расчёта) double array3[]; // Массив-буфер3 индикатора (4-й массив для расчёта) double color_indexes[]; // Массив-буфер индексов цветов индикатора color clrs[]; // Массив цветов, назначенных буферу string descript; // Описание буфера //--- Возвращает флаг цветного буфера bool IsColoredBuffer(void) { return colored; } //--- (1) Устанавливает, (2) возвращает стиль рисования буфера, (3) номер соответствующего буфера исходного индикатора void SetBufferDrawType(const ENUM_DRAW_TYPE type,const uint buff_source) { draw_type=type; source=buff_source; switch(draw_type) { case DRAW_COLOR_LINE : case DRAW_COLOR_SECTION : case DRAW_COLOR_HISTOGRAM : case DRAW_COLOR_HISTOGRAM2 : case DRAW_COLOR_ARROW : case DRAW_COLOR_ZIGZAG : case DRAW_COLOR_BARS : case DRAW_COLOR_CANDLES : colored=true; break; default : colored=false; break; } } ENUM_DRAW_TYPE DrawType(void) { return draw_type; } uint BufferFrom(void) { return source; } //--- (1) Устанавливает, (2) возвращает инициализирующее значение void SetInitValue(const double value) { init_value=value; } double InitValue(void) { return init_value; } //--- (1) Устанавливает, (2) возвращает инициализирующее значение индекса цвета void SetInitColorIdx(const uchar idx) { init_color_idx=idx; } uchar InitColorIdx(void) { return init_color_idx; } //--- (1) Устанавливает, (2) возвращает сдвиг буфера void SetShift(const int value) { shift=value; } int Shift(void) { return shift; } //--- (1) Возвращает размер массива буфера, (2) изменяет размер массива буфера, //--- (3) инициализирует массив установленным "пустым" значением uint BufferSize(void) { return array0.Size(); } bool BuffResize(const int new_size) { return ResizeArrays(new_size); } int InitBuffer(void) { return InitArrays(); } //--- (1) Возвращает размер массива буфера индексов цвета, uint BufferColorIdxSize(void) { return color_indexes.Size(); } //--- (1) Устанавливает, (2) возвращает значение цвета по индексу void SetColorToIdx(const uchar idx,const color clr) { if(idx>(int)clrs.Size()-1) { ResetLastError(); if(ArrayResize(clrs,idx+1)!=idx+1) { PrintFormat("%s: ArrayResize 'clrs' failed. Error %lu",__FUNCTION__,GetLastError()); return; } } clrs[idx]=clr; } color ColorByIdx(const uchar idx){ return(idxcompared_param.type || this_param.integer_value>compared_param.integer_value || this_param.string_value>compared_param.string_value || this_param.double_value>compared_param.double_value ) return 1; else if(this_param.typecompared.ID() ? 1 : this.ID()compared.Handle() ? 1 : this.Handle()compared.Category() ? 1 : this.Category()compared.Symbol() ? 1 : this.Symbol()compared.Timeframe() ? 1 : this.Timeframe()compared.Description() ? 1 : this.Description()=TIMER_COUNT_1) { //--- вызываем функцию CopyTime (удержание таймсерии) и сбрасываем счётчик datetime array[1]; ::CopyTime(this.m_symbol,this.m_timeframe,0,1,array); count1=0; } //--- Если счётчик таймера 2 достиг заданного значения if(count2>=TIMER_COUNT_2) { static int count=0; //--- если прошлый расчёт индикатора был неуспешным - эмулируем тик с сообщением в журнал if(!this.m_success) { if(::ChartSetSymbolPeriod(0,::Symbol(),::Period())) { count++; ::PrintFormat("%s::%s: Tick emulation. Attempt %ld of 3 ...",__FUNCTION__,this.Title(),count); if(count>2) { count=0; this.m_success=true; } } } //--- сбрасываем счётчик count2=0; } //--- Увеличиваем счётчики таймеров count1++; count2++; } //+------------------------------------------------------------------+ //| Создаёт индикатор, возвращает хэндл | //+------------------------------------------------------------------+ int CIndMSTF::CreateIndicator(void) { //--- Создаём наименование индикатора для вывода в журнал string name=::StringFormat("%s(%s,%s)",::StringSubstr(::EnumToString(this.m_type),4),this.m_symbol,this.TimeframeDescription()); //--- Создаём расчётную часть индикатора ::ResetLastError(); this.m_handle=::IndicatorCreate(this.m_symbol,this.m_timeframe,this.m_type,this.m_param.Size(),this.m_param); //--- Если расчётная часть не создана - выводим в журнал сообщение о неудачном создании индикатора if(this.m_handle==INVALID_HANDLE) ::PrintFormat("%s: Failed to create indicator handle %s. Error %ld",__FUNCTION__,name,::GetLastError()); //--- Если индикатор создан - устанавливаем индексацию массивов индикатора не как у таймсерии else this.SetAsSeriesOff(); //--- Возвращаем хэндл созданного индикатора, либо -1 при неудаче return this.m_handle; } //+------------------------------------------------------------------+ //| Изменяет размер указанного буфера индикатора | //+------------------------------------------------------------------+ bool CIndMSTF::BufferResize(const uint buffer_num,const int new_buff_size) { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал и возвращаем false if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); return false; } //--- Изменяем размер буфера ::ResetLastError(); bool res=this.m_buffers[buffer_num].BuffResize(new_buff_size); //--- При неудаче выводим сообщение в журнал if(!res) ::PrintFormat("%s::%s: Buffer(%lu) resize failed. Error %lu",__FUNCTION__,this.Title(),buffer_num,::GetLastError()); //--- Возвращаем результат изменения размера массива буфера return res; } //+------------------------------------------------------------------+ //| Изменяет размер всех буферов индикатора | //+------------------------------------------------------------------+ bool CIndMSTF::BuffersResize(const int new_buff_size) { //--- В цикле по всем буферам индикатора добавляем к переменной res результат изменения размера каждого очередного буфера bool res=true; int total=(int)this.BuffersTotal(); for(int i=0;ithis.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); return false; } //--- Изменяем размер массива буфера bool res=this.BufferResize(buffer_num,new_buff_size); //--- При удачном изменении размера инициализируем буфер установленным инициализирующим значением if(res) this.m_buffers[buffer_num].InitBuffer(); //--- Возвращаем результат return res; } //+------------------------------------------------------------------+ //| Инициализирует все буферы индикатора | //+------------------------------------------------------------------+ bool CIndMSTF::BuffersInitialize(const int new_buff_size) { //--- В цикле по всем буферам индикатора добавляем к переменной res результат изменения размера каждого очередного буфера //--- При удачном изменении размера инициализируем буфер установленным инициализирующим значением bool res=true; int total=(int)this.BuffersTotal(); for(int i=0;ithis.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); return; } //--- Устанавливаем новое инициализирующее значение для указанного буфера this.m_buffers[buffer_num].SetInitValue(value); } //+------------------------------------------------------------------+ //| Возвращает инициализирующее значение указанного буфера | //+------------------------------------------------------------------+ double CIndMSTF::BufferInitValue(const uint buffer_num) const { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); //--- Если у индикатора есть буферы, то возвращаем инициализирующее значение самого первого, иначе - EMPTY_VALUE return(this.BuffersTotal()>0 ? this.BufferInitValue(0) : EMPTY_VALUE); } //--- Возвращаем инициализирующее значение запрошенного буфера return this.m_buffers[buffer_num].InitValue(); } //+------------------------------------------------------------------+ //| Устанавливает инициализирующее значение индекса цвета | //| для указанного буфера | //+------------------------------------------------------------------+ void CIndMSTF::SetBufferInitColorIndex(const uint buffer_num,const uchar index) { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал и уходим if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); return; } //--- Устанавливаем новое инициализирующее значение индекса цвета для указанного буфера this.m_buffers[buffer_num].SetInitColorIdx(index); } //+------------------------------------------------------------------+ //| Возвращает инициализирующее значение индекса цвета | //| для указанного буфера | //+------------------------------------------------------------------+ uchar CIndMSTF::BufferInitColorIndex(const uint buffer_num) const { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); //--- Если у индикатора есть буферы, то возвращаем инициализирующее значение индекса цвета самого первого, иначе - 0 return uchar(this.BuffersTotal()>0 ? this.m_buffers[0].InitColorIdx() : 0); } //--- Возвращаем инициализирующее значение индекса цвета запрошенного буфера return this.m_buffers[buffer_num].InitColorIdx(); } //+------------------------------------------------------------------+ //| Устанавливает значение цвета по индексу для указанного буфера | //+------------------------------------------------------------------+ void CIndMSTF::SetBufferColorToIndex(const uint buffer_num,const uchar color_idx,const color clr) { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал и уходим if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); return; } //--- Устанавливаем новое значение цвета по индексу для указанного буфера this.m_buffers[buffer_num].SetColorToIdx(color_idx,clr); } //+------------------------------------------------------------------+ //| Возвращает значение цвета по индексу для указанного буфера | //+------------------------------------------------------------------+ color CIndMSTF::BufferColorByIndex(const uint buffer_num,const uchar color_idx) { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); //--- Если у индикатора есть буферы, то возвращаем инициализирующее значение индекса цвета самого первого, иначе - 0 return clrNONE; } //--- Возвращаем значение цвета по индексу для запрошенного буфера return this.m_buffers[buffer_num].ColorByIdx(color_idx); } //+------------------------------------------------------------------+ //| Возвращает флаг цветного буфера | //+------------------------------------------------------------------+ bool CIndMSTF::IsColoredBuffer(const uint buffer_num) const { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); //--- Возвращаем false return false; } //--- Возвращаем флаг цветности для указанного буфера return this.m_buffers[buffer_num].IsColoredBuffer(); } //+------------------------------------------------------------------+ //| Устанавливает значение сдвига для указанного буфера | //+------------------------------------------------------------------+ void CIndMSTF::SetBufferShift(const uint buffer_num,const int value) { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал и уходим if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); return; } //--- Устанавливаем значение сдвига для буфера this.m_buffers[buffer_num].SetShift(value); } //+------------------------------------------------------------------+ //| Возвращает значение сдвига указанного буфера | //+------------------------------------------------------------------+ double CIndMSTF::BufferShift(const uint buffer_num) const { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); //--- Если у индикатора есть буферы, то возвращаем значение сдвига самого первого, иначе - 0 return(this.BuffersTotal()>0 ? this.m_buffers[0].Shift() : 0); } //--- Возвращаем значение сдвига запрошенного буфера return this.m_buffers[buffer_num].Shift(); } //+------------------------------------------------------------------+ //| Устанавливает стиль рисования указанного буфера | //+------------------------------------------------------------------+ void CIndMSTF::SetBufferDrawType(const uint buffer_num,const ENUM_DRAW_TYPE type,const uint buff_source) { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал и уходим if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); return; } //--- Устанавливаем стиль рисования для буфера this.m_buffers[buffer_num].SetBufferDrawType(type,buff_source); } //+------------------------------------------------------------------+ //| Возвращает стиль рисования указанного буфера | //+------------------------------------------------------------------+ ENUM_DRAW_TYPE CIndMSTF::BufferDrawType(const uint buffer_num) { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); //--- Если у индикатора есть буферы, то возвращаем значение сдвига самого первого, иначе - 0 return(this.BuffersTotal()>0 ? this.m_buffers[0].DrawType() : DRAW_NONE); } //--- Возвращаем стиль рисования запрошенного буфера return this.m_buffers[buffer_num].DrawType(); } //+------------------------------------------------------------------+ //| Возвращает номер соответствующего буфера исходного индикатора | //+------------------------------------------------------------------+ uint CIndMSTF::BufferFrom(const uint buffer_num) { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); //--- Если у индикатора есть буферы, то возвращаем значение сдвига самого первого, иначе - 0 return(this.BuffersTotal()>0 ? this.m_buffers[0].Shift() : 0); } //--- Возвращаем номер соответствующего буфера исходного индикатора для запрошенного буфера return this.m_buffers[buffer_num].BufferFrom(); } //+------------------------------------------------------------------+ //| Копирует данные указанного массива указанного буфера | //+------------------------------------------------------------------+ bool CIndMSTF::CopyArray(const uint buff_num,const uint array_num,const int to_copy,double &array[]) { ::ResetLastError(); //--- Копируем либо два последних бара в массив array, либо все имеющиеся исторические данные из массива расчётной части индикатора в массив-буфер объекта индикатора int copied=0; if(to_copy==this.m_bars_to_calculate) { switch(array_num) { case 0 : case 1 : case 2 : case 3 : copied=::CopyBuffer(this.m_handle,this.m_buffers[buff_num].BufferFrom(), -this.m_buffers[buff_num].Shift(),to_copy,array); break; case 4 : copied=::CopyBuffer(this.m_handle,this.m_buffers[buff_num].BufferFrom()+1,-this.m_buffers[buff_num].Shift(),to_copy,array); break; default : break; } } else { switch(array_num) { case 0 : copied=::CopyBuffer(this.m_handle,this.m_buffers[buff_num].BufferFrom(), -this.m_buffers[buff_num].Shift(),to_copy,this.m_buffers[buff_num].array0); break; case 1 : copied=::CopyBuffer(this.m_handle,this.m_buffers[buff_num].BufferFrom(), -this.m_buffers[buff_num].Shift(),to_copy,this.m_buffers[buff_num].array1); break; case 2 : copied=::CopyBuffer(this.m_handle,this.m_buffers[buff_num].BufferFrom(), -this.m_buffers[buff_num].Shift(),to_copy,this.m_buffers[buff_num].array2); break; case 3 : copied=::CopyBuffer(this.m_handle,this.m_buffers[buff_num].BufferFrom(), -this.m_buffers[buff_num].Shift(),to_copy,this.m_buffers[buff_num].array3); break; case 4 : copied=::CopyBuffer(this.m_handle,this.m_buffers[buff_num].BufferFrom()+1,-this.m_buffers[buff_num].Shift(),to_copy,this.m_buffers[buff_num].color_indexes); break; default : break; } } //--- Если копирование успешно if(copied>0) return true; //--- Если скопированы не все данные //--- Если CopyBuffer вернула -1, то это означает начало загрузки исторических данных //--- выведем сообщение об этом в журнал if(copied==WRONG_VALUE) ::PrintFormat("%s::%s: Start downloading data by %s/%s. Waiting for the next tick...",__FUNCTION__,this.Title(),this.m_symbol,this.TimeframeDescription()); //--- В любом ином случае - ещё не все данные удалось скопировать //--- выведем сообщение об этом в журнал else ::PrintFormat("%s::%s: Not all data was copied. Data available: %lu, total copied: %ld",__FUNCTION__,this.Title(),this.m_rates_total,copied); return false; } //+------------------------------------------------------------------+ //| Копирует данные всех массивов указанного буфера | //+------------------------------------------------------------------+ bool CIndMSTF::CopyArrays(const uint buff_num,const int to_copy) { bool res=true; if(to_copy==this.m_bars_to_calculate) { int total=(int)this.m_array_data.Size(); switch(this.BufferDrawType(buff_num)) { //--- Один буфер case DRAW_LINE : case DRAW_HISTOGRAM : case DRAW_ARROW : case DRAW_SECTION : res=this.CopyArray(buff_num,0,to_copy,this.m_array_data); if(res) { for(int i=0;i0 ? sec : 1))+1; //--- В переменную bars запишем меньшее значение из рассчитанного количества баров и максимального количества баров, доступных в терминале bars=(int)::fmin(date_bars,::TerminalInfoInteger(TERMINAL_MAXBARS)); } //--- Запишем в m_rates_total полученное количество доступных баров if(this.m_rates_total!=bars) this.m_rates_total=bars; //--- Если количество доступных баров получено, и их два и меньше, if(this.m_rates_total>=0 && this.m_rates_total<3) { //--- Выведем в журнал сообщение о слишком маленьком количестве доступных баров ::PrintFormat("%s::%s: Not enough data for calculation: %ld bars. Waiting for the next tick...",__FUNCTION__,this.Title(),this.m_rates_total); //--- установим тип ошибки, к флагу ошибки добавим false и вернём false this.m_type_err=ERR_TYPE_NO_DATA; this.m_success=false; return false; } //--- Рассчитаем количество необходимых баров для расчёта индикатора //--- Либо вся доступная история, либо 1 при открытии нового бара, либо 0 на текущем тике this.m_limit=this.m_rates_total-this.m_prev_calculated; this.m_prev_calculated=this.Calculated(); //--- Получаем количество буферов индикатора int total=(int)this.BuffersTotal(); //--- Если рассчитанное значение m_limit больше 1 - значит это либо первый запуск, либо изменения в исторических данных //--- В этом случае необходим полный перерасчёт индикатора if(this.m_limit>1) { //--- В цикле по количеству буферов индикатора for(int i=0;ithis.m_rates_total ? this.m_rates_total : this.m_prev_calculated); //--- Если не все массивы успешно скопированы - запишем в m_success значение false if(!this.CopyArrays(i,to_copy)) this.m_success &=false; } //--- Если после цикла есть ошибки - возвращаем false if(!this.m_success) { this.m_type_err=ERR_TYPE_NO_DATA; return false; } //--- Всё успешно - вернём true this.m_type_err=ERR_TYPE_NO_ERROR; this.m_success=true; return true; } //--- Если рассчитанное значение m_limit меньше, либо равно 1 - значит это либо открытие нового бара (m_limit==1), либо текущий тик (m_limit==0) //--- В этом случае необходимо рассчитать указанное в переменной m_bars_to_calculate количество баров - текущий и остальные if(this.m_limit<=1) { //--- В цикле по количеству буферов индикатора for(int i=0;i1 && this.m_limit>1) { ::PrintFormat("%s::%s First start, or historical data has been changed. Initialize Buffer(%lu)",__FUNCTION__,this.Title(),buffer_num); ::ArrayInitialize(buffer,this.BufferInitValue(buffer_num)); } //--- Устанавливаем значение счётчика цикла (не более максимального количества баров в терминале на графике) int count=(limit<=1 ? (int)this.m_bars_to_calculate : ::fmin(::TerminalInfoInteger(TERMINAL_MAXBARS),limit)); //--- В цикле от нулевого бара до значения счётчика цикла for(int i=0;i(int)this.m_bars_to_calculate-1) { //--- Узнаём какому времени данного класса принадлежит бар текущего таймфрейма графика, соответствующий индексу цикла ::ResetLastError(); if(::CopyTime(symbol,timeframe,i,1,this.m_array_time)!=1) { //--- Если данных нет в терминале - идём дальше if(::GetLastError()==4401) continue; //--- Ошибка получения существующих данных - возвращаем false this.m_success &=false; return false; } //--- По времени бара текущего таймфрейма графика находим соответствующий индекс бара периода графика в массиве-буфере объекта класса int bar=::iBarShift(this.m_symbol,this.m_timeframe,this.m_array_time[0]); if(bar==WRONG_VALUE) { this.m_success &=false; continue; } //--- записываем в буфер индикатора по индексу цикла значение, полученное из буфера расчётной части buffer[i]=this.GetData(buffer_num,array_num,bar); } //--- Если это текущий (нулевой) бар или бар, с индексом меньшим, либо равным m_bars_to_calculate-1 else { //--- Получаем время баров по символу/таймфрейму объекта класса в количестве m_bars_to_calculate if(::CopyTime(this.m_symbol,this.m_timeframe,0,this.m_bars_to_calculate,this.m_array_time)!=this.m_bars_to_calculate) { this.m_success=false; return false; } //--- Получаем количество баров текущего периода графика, содержащихся в периоде графика объекта класса int num_bars=::PeriodSeconds(this.m_timeframe)/::PeriodSeconds(timeframe); if(num_bars<1) num_bars=1; //--- В цикле по массиву полученных времён баров for(int j=0;j<(int)this.m_array_time.Size();j++) { //--- По времени бара в массиве-буфере объекта класса получаем соответствующий бар на графике int barN=::iBarShift(symbol,timeframe,this.m_array_time[j]); if(barN==WRONG_VALUE) { this.m_success &=false; return false; } //--- Рассчитываем конечный бар на графике для копирования данных из буфера расчётной части индикатора int end=barN-num_bars; if(end<0) end=-1; //--- В цикле от бара barN до бара end копируем данные из массива-буфера расчётной части в рисуемый буфер индикатора на графике for(int n=barN;n>end;n--) buffer[n]=this.GetData(buffer_num,array_num,this.m_bars_to_calculate-1-j); } } } //--- Если таймфрейм графика старше таймфрейма объекта класса, else if(timeframe>this.m_timeframe) { //--- Получаем количество баров периода графика объекта класса, содержащихся в баре текущего периода графика int num_bars=::PeriodSeconds(timeframe)/::PeriodSeconds(this.m_timeframe); //--- Узнаём какому времени данного класса принадлежит бар текущего таймфрейма графика, соответствующий индексу цикла ::ResetLastError(); if(::CopyTime(symbol,timeframe,i,1,this.m_array_time)!=1) { //--- Если данных нет в терминале - идём дальше if(::GetLastError()==4401) continue; //--- Ошибка получения существующих данных - возвращаем false this.m_success &=false; return false; } //--- По времени бара текущего таймфрейма графика находим соответствующий индекс бара периода графика в массиве-буфере объекта класса //--- Этот бар будет первым из нескольких баров объекта класса в количестве num_bars, входящих в состав бара на графике int bar=::iBarShift(this.m_symbol,this.m_timeframe,this.m_array_time[0]); if(bar==WRONG_VALUE) { this.m_success &=false; continue; } //--- Рассчитываем индекс последнего бара для копирования в цикле int end=bar-num_bars; if(end<0) end=-1; //--- В цикле от первого до последнего бара, входящих в состав бара старшего периода графика for(int j=bar;j>end;j--) { //--- Узнаём какому времени данного класса принадлежит бар текущего таймфрейма графика, соответствующий индексу цикла ::ResetLastError(); if(::CopyTime(this.m_symbol,this.m_timeframe,j,1,this.m_array_time)!=1) { //--- Если данных нет в терминале - идём дальше if(::GetLastError()==4401) continue; //--- Ошибка получения существующих данных - возвращаем false this.m_success &=false; return false; } //--- Получаем номер бара на графике, соответствующий времени массива-буфера расчётной части по индексу цикла j int barN=::iBarShift(symbol,timeframe,this.m_array_time[0]); //--- Получаем данные бара j в массиве-буфере расчётной части и данные бара barN, содержащиеся в буфере индикатора на графике double value_data=this.GetData(buffer_num,array_num,j); double value_buff=buffer[barN]; //--- Если бар на графике имеет пустое значение, то записываем в него данные из массива-буфера расчётной части. Либо, //--- если на графике уже есть данные, то новые данные в этот бар записываем только, если в данных содержится не пустое значение. if(value_buff==this.BufferInitValue(buffer_num) || (value_buff!=this.BufferInitValue(buffer_num) && value_data!=this.BufferInitValue(buffer_num))) buffer[barN]=value_data; } } } } //--- Устанавливаем изначальную индексацию переданного в метод массива буфера ::ArraySetAsSeries(buffer,as_series); //--- Успешно return true; } //+------------------------------------------------------------------+ //| Заполняет переданные в метод рисуемый массив | //| и массив индексов цвета данными из буфера класса | //+------------------------------------------------------------------+ bool CIndMSTF::DataToColorBuffer(const string symbol_to,const ENUM_TIMEFRAMES timeframe_to,const uint buffer_num,const uint array_num,const int limit,double &plot_buffer[],double &color_buffer[]) { //--- Устанавливаем флаг успешности this.m_success=true; //--- Получаем направление индексации переданного в метод массива буфера и, //--- если индексация не как у таймсерии, - устанавливаем индексацию как у таймсерии bool as_series_plot=::ArrayGetAsSeries(plot_buffer); if(!as_series_plot) ::ArraySetAsSeries(plot_buffer,true); bool as_series_color=::ArrayGetAsSeries(color_buffer); if(!as_series_color) ::ArraySetAsSeries(color_buffer,true); //--- Устанавливаем наименование символа и значение таймфрейма, переданные в метод string symbol=(symbol_to=="" || symbol_to==NULL ? ::Symbol() : symbol_to); ENUM_TIMEFRAMES timeframe=(timeframe_to==PERIOD_CURRENT ? ::Period() : timeframe_to); datetime array[2]; //--- Если это первый запуск, или изменения в истории - инициальзируем массив буфера, переданный в метод if(limit>1 && this.m_limit>1) { ::PrintFormat("%s::%s First start, or historical data has been changed. Initialize Buffer(%lu)",__FUNCTION__,this.Title(),buffer_num); ::ArrayInitialize(plot_buffer,this.BufferInitValue(buffer_num)); ::ArrayInitialize(color_buffer,this.BufferInitColorIndex(buffer_num)); } //--- Устанавливаем значение счётчика цикла (не более максимального количества баров в терминале на графике) int count=(limit<=1 ? 2 : ::fmin(::TerminalInfoInteger(TERMINAL_MAXBARS),limit)); //--- В цикле от нулевого бара до значения счётчика цикла for(int i=0;i1) { plot_buffer[i]=this.GetData(buffer_num,array_num,bar); color_buffer[i]=this.GetColorData(buffer_num,bar); } //--- Если это текущий (нулевой) или предыдущий (первый) бар else { //--- Получаем время баров 0 и 1 по символу/таймфрейму объекта класса if(::CopyTime(this.m_symbol,this.m_timeframe,0,2,array)!=2) { this.m_success &=false; return false; } //--- Получаем по времени индексы текущего и предыдущего баров на графике, символ/период которого передан в метод int bar0=::iBarShift(symbol,timeframe,array[1]); int bar1=::iBarShift(symbol,timeframe,array[0]); if(bar0==WRONG_VALUE || bar1==WRONG_VALUE) { this.m_success &=false; return false; } //--- Если таймфрейм графика младше таймфрейма объекта класса, if(timeframe=0;j--) { plot_buffer[j]=this.GetData(buffer_num,array_num,(j>bar0 ? 1 : 0)); color_buffer[j]=this.GetColorData(buffer_num,(j>bar0 ? 1 : 0)); } } //--- Если таймфрейм графика старше таймфрейма объекта класса, else { //--- Получаем время текущего и предыдущего баров по символу/таймфрейму текущего графика if(::CopyTime(symbol,timeframe,0,2,array)!=2) { this.m_success &=false; return false; } //--- Получаем по времени индексы баров в буфере расчётной части индикатора, соответствующие времени текущего и предыдущего баров на графике int bar0=::iBarShift(this.m_symbol,this.m_timeframe,array[1]); int bar1=::iBarShift(this.m_symbol,this.m_timeframe,array[0]); //--- Записываем в буфер индикатора по индексам 1 и 0 значения из соответствующих индексов буфера расчётной части plot_buffer[1]=this.GetData(buffer_num,array_num,bar1); plot_buffer[0]=this.GetData(buffer_num,array_num,bar0); color_buffer[1]=this.GetColorData(buffer_num,bar1); color_buffer[0]=this.GetColorData(buffer_num,bar0); } } } } //--- Устанавливаем изначальную индексацию переданного в метод массива буфера ::ArraySetAsSeries(plot_buffer,as_series_plot); ::ArraySetAsSeries(color_buffer,as_series_color); //--- Успешно return true; } //+------------------------------------------------------------------+ //| Возвращает данные указанного буфера как есть | //+------------------------------------------------------------------+ double CIndMSTF::GetData(const uint buffer_num,const uint array_num,const int index) const { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); //--- Если у индикатора есть буферы, то возвращаем "пустое" значение самого первого, иначе - EMPTY_VALUE return(this.BuffersTotal()>0 ? this.BufferInitValue(0) : EMPTY_VALUE); } //--- Если указан не правильный индекс - возвращаем "пустое" значение указанного буфера if(index<0 || index>(int)this.DataTotal(buffer_num,array_num)-1) return this.BufferInitValue(buffer_num); //--- Рассчитываем реальный индекс в массиве-буфере и возвращаем значение по этому индексу int n=int(this.DataTotal(buffer_num,array_num)-1-index); switch(array_num) { case 0 : return this.m_buffers[buffer_num].array0[n]; case 1 : return this.m_buffers[buffer_num].array1[n]; case 2 : return this.m_buffers[buffer_num].array2[n]; case 3 : return this.m_buffers[buffer_num].array3[n]; case 4 : return this.m_buffers[buffer_num].color_indexes[n]; default: break; } return EMPTY_VALUE; } //+-------------------------------------------------------------------+ //| Возвращает данные указанного буфера на указанный символ/таймфрейм | //+-------------------------------------------------------------------+ double CIndMSTF::GetDataTo(const string symbol_to,const ENUM_TIMEFRAMES timeframe_to,const uint buffer_num,const uint array_num,const int index) const { //--- Если указан текущий символ/период графика if(timeframe_to==::Period() && this.m_timeframe==::Period() && symbol_to==::Symbol() && this.m_symbol==::Symbol()) return this.GetData(buffer_num,array_num,index); //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); //--- Если у индикатора есть буферы, то возвращаем "пустое" значение самого первого, иначе - EMPTY_VALUE return(this.BuffersTotal()>0 ? this.BufferInitValue(0) : EMPTY_VALUE); } //--- Узнаём какому времени данного класса принадлежит бар текущего таймфрейма графика, соответствующий индексу цикла datetime array[]; if(::CopyTime(symbol_to,timeframe_to,index,1,array)!=1) return this.BufferInitValue(buffer_num); //--- По времени бара текущего таймфрейма графика находим соответствующий индекс бара периода графика данного класса int bar=iBarShift(this.m_symbol,this.m_timeframe,array[0]); //--- Если бар не найден - возвращаем "пустое" значение, установленное для буфера if(bar==WRONG_VALUE) return this.BufferInitValue(buffer_num); //--- Возвращаем значение из буфера объекта-индикатора по найденному индексу return this.GetData(buffer_num,array_num,bar); } //+------------------------------------------------------------------+ //| Возвращает данные указанного буфера индексов цвета как есть | //+------------------------------------------------------------------+ double CIndMSTF::GetColorData(const uint buffer_num,const int index) const { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал и возвращаем 0 if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); return 0; } //--- Если это не цветной буфер - сообщаем об этом в журнал и возвращаем 0 if(!this.IsColoredBuffer(buffer_num)) { ::PrintFormat("%s: Buffer %lu is not a color buffer",__FUNCTION__,buffer_num); return 0; } //--- Если указан не правильный индекс - возвращаем "пустое" значение указанного буфера цвета if(index<0 || index>(int)this.DataTotal(buffer_num,4)-1) return this.BufferInitColorIndex(buffer_num); //--- Рассчитываем реальный индекс в массиве-буфере цвета и возвращаем значение по этому индексу int n=int(this.DataTotal(buffer_num,4)-1-index); return this.m_buffers[buffer_num].color_indexes[n]; } //+------------------------------------------------------------------+ //| Возвращает данные указанного буфера индексов цвета | //| на указанный символ/таймфрейм | //+------------------------------------------------------------------+ double CIndMSTF::GetColorDataTo(const string symbol_to,const ENUM_TIMEFRAMES timeframe_to,const uint buffer_num,const int index) const { //--- Если указан текущий символ/период графика if(timeframe_to==::Period() && this.m_timeframe==::Period() && symbol_to==::Symbol() && this.m_symbol==::Symbol()) return this.GetColorData(buffer_num,index); //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал и возвращаем 0 if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); return 0; } //--- Если это не цветной буфер - сообщаем об этом в журнал и возвращаем 0 if(!this.IsColoredBuffer(buffer_num)) { ::PrintFormat("%s: Buffer %lu is not a color buffer",__FUNCTION__,buffer_num); return 0; } //--- Узнаём какому времени данного класса принадлежит бар текущего таймфрейма графика, соответствующий индексу цикла datetime array[]; if(::CopyTime(symbol_to,timeframe_to,index,1,array)!=1) return this.BufferInitColorIndex(buffer_num); //--- По времени бара текущего таймфрейма графика находим соответствующий индекс бара периода графика данного класса int bar=iBarShift(this.m_symbol,this.m_timeframe,array[0]); //--- Если бар не найден - возвращаем "пустое" значение, установленное для буфера цвета if(bar==WRONG_VALUE) return this.BufferInitColorIndex(buffer_num); //--- Возвращаем значение из буфера цвета объекта-индикатора по найденному индексу return this.GetColorData(buffer_num,bar); //--- Рассчитываем реальный индекс в массиве-буфере цвета и возвращаем значение по этому индексу int n=int(this.DataTotal(buffer_num,4)-1-bar); return this.m_buffers[buffer_num].color_indexes[n]; } //+------------------------------------------------------------------+ //| Возвращает состояние линии индикатора как есть | //+------------------------------------------------------------------+ ENUM_LINE_STATE CIndMSTF::BufferLineState(const uint buffer_num,const uint array_num,const int index) const { //--- Получаем значения линии индикатора со смещением (0,1,2) относительно переданного индекса const double value0=this.GetData(buffer_num,array_num,index); const double value1=this.GetData(buffer_num,array_num,index+1); const double value2=this.GetData(buffer_num,array_num,index+2); //--- Если хоть одно из значений получить не удалось - возвращаем неопределённое значение if(value0==EMPTY_VALUE || value1==EMPTY_VALUE || value2==EMPTY_VALUE) return LINE_STATE_NONE; //--- Разворот линии вверх (value2>value1 && value0>value1) if(::NormalizeDouble(value2-value1,this.m_digits)>0 && ::NormalizeDouble(value0-value1,this.m_digits)>0) return LINE_STATE_TURN_UP; //--- Направление линии вверх (value2<=value1 && value0>value1) else if(::NormalizeDouble(value2-value1,this.m_digits)<=0 && ::NormalizeDouble(value0-value1,this.m_digits)>0) return LINE_STATE_UP; //--- Остановка направления линии вверх (value2<=value1 && value0==value1) else if(::NormalizeDouble(value2-value1,this.m_digits)<=0 && ::NormalizeDouble(value0-value1,this.m_digits)==0) return LINE_STATE_STOP_UP; //--- Разворот линии вниз (value2=value1 && value0=0 && ::NormalizeDouble(value0-value1,this.m_digits)<0) return LINE_STATE_DOWN; //--- Остановка направления линии вниз (value2>=value1 && value0==value1) else if(::NormalizeDouble(value2-value1,this.m_digits)>=0 && ::NormalizeDouble(value0-value1,this.m_digits)==0) return LINE_STATE_STOP_DOWN; //--- Неопределённое состояние return LINE_STATE_NONE; } //+------------------------------------------------------------------+ //| Возвращает состояние линии индикатора с учётом символа/периода | //+------------------------------------------------------------------+ ENUM_LINE_STATE CIndMSTF::BufferLineState(const string symbol_from,const ENUM_TIMEFRAMES timeframes_from,const uint buffer_num,const uint array_num,const int index) const { //--- Определяем переданные в метод символ/период графика string symbol=(symbol_from=="" || symbol_from==NULL ? ::Symbol() : symbol_from); ENUM_TIMEFRAMES timeframe=(timeframes_from==PERIOD_CURRENT ? ::Period() : timeframes_from); //--- Если получаем данные от символа/периода, равные текущему графику - возвращаем состояние из буфера "как есть" if(symbol==::Symbol() && symbol==this.m_symbol && timeframe==::Period() && timeframe==this.m_timeframe) return this.BufferLineState(buffer_num,array_num,index); //--- Объявляем переменные для поиска нужных баров на текущем графике datetime array[1]; int bar0=WRONG_VALUE; int bar1=WRONG_VALUE; int bar2=WRONG_VALUE; //--- Получаем время первого бара на графике ::ResetLastError(); if(::CopyTime(symbol,timeframe,index,1,array)!=1) { ::PrintFormat("%s: CopyTime for %s/%s, bar %ld failed. Error %lu",__FUNCTION__,symbol,::StringSubstr(::EnumToString(timeframe),7),index,::GetLastError()); return LINE_STATE_NONE; } //--- Получаем индекс первого бара в буфере объекта-индикатора по времени открытия бара на графике bar0=::iBarShift(this.m_symbol,this.m_timeframe,array[0]); if(bar0==WRONG_VALUE) { ::PrintFormat("%s: iBarShift for %s/%s, time %s failed. Error %lu",__FUNCTION__,this.m_symbol,this.TimeframeDescription(),string(array[0]),::GetLastError()); return LINE_STATE_NONE; } //--- Получаем время второго бара на графике ::ResetLastError(); if(::CopyTime(symbol,timeframe,index+1,1,array)!=1) { ::PrintFormat("%s: CopyTime for %s/%s, bar %ld failed. Error %lu",__FUNCTION__,symbol,::StringSubstr(::EnumToString(timeframe),7),index+1,::GetLastError()); return LINE_STATE_NONE; } //--- Получаем индекс второго бара в буфере объекта-индикатора по времени открытия бара на графике bar1=::iBarShift(this.m_symbol,this.m_timeframe,array[0]); if(bar1==WRONG_VALUE) { ::PrintFormat("%s: iBarShift for %s/%s, time %s failed. Error %lu",__FUNCTION__,this.m_symbol,this.TimeframeDescription(),string(array[0]),::GetLastError()); return LINE_STATE_NONE; } //--- Получаем время третьего бара на графике ::ResetLastError(); if(::CopyTime(symbol,timeframe,index+2,1,array)!=1) { ::PrintFormat("%s: CopyTime for %s/%s, bar %ld failed. Error %lu",__FUNCTION__,symbol,::StringSubstr(::EnumToString(timeframe),7),index+2,::GetLastError()); return LINE_STATE_NONE; } //--- Получаем индекс третьего бара в буфере объекта-индикатора по времени открытия бара на графике bar2=::iBarShift(this.m_symbol,this.m_timeframe,array[0]); if(bar2==WRONG_VALUE) { ::PrintFormat("%s: iBarShift for %s/%s, time %s failed. Error %lu",__FUNCTION__,this.m_symbol,this.TimeframeDescription(),string(array[0]),::GetLastError()); return LINE_STATE_NONE; } //--- Получаем значения линии индикатора со смещением (0,1,2) относительно переданного индекса const double value0=this.GetData(buffer_num,array_num,bar0); const double value1=this.GetData(buffer_num,array_num,bar1); const double value2=this.GetData(buffer_num,array_num,bar2); //--- Если хоть одно из значений получить не удалось - возвращаем неопределённое значение if(value0==EMPTY_VALUE || value1==EMPTY_VALUE || value2==EMPTY_VALUE) return LINE_STATE_NONE; //--- Разворот линии вверх (value2>value1 && value0>value1) if(::NormalizeDouble(value2-value1,this.m_digits)>0 && ::NormalizeDouble(value0-value1,this.m_digits)>0) return LINE_STATE_TURN_UP; //--- Направление линии вверх (value2<=value1 && value0>value1) else if(::NormalizeDouble(value2-value1,this.m_digits)<=0 && ::NormalizeDouble(value0-value1,this.m_digits)>0) return LINE_STATE_UP; //--- Остановка направления линии вверх (value2<=value1 && value0==value1) else if(::NormalizeDouble(value2-value1,this.m_digits)<=0 && ::NormalizeDouble(value0-value1,this.m_digits)==0) return LINE_STATE_STOP_UP; //--- Разворот линии вниз (value2=value1 && value0=0 && ::NormalizeDouble(value0-value1,this.m_digits)<0) return LINE_STATE_DOWN; //--- Остановка направления линии вниз (value2>=value1 && value0==value1) else if(::NormalizeDouble(value2-value1,this.m_digits)>=0 && ::NormalizeDouble(value0-value1,this.m_digits)==0) return LINE_STATE_STOP_DOWN; //--- Неопределённое состояние return LINE_STATE_NONE; } //+------------------------------------------------------------------+ //| Возвращает состояние линии относительно указанного уровня | //+------------------------------------------------------------------+ ENUM_LINE_STATE CIndMSTF::BufferLineStateRelative(const int buffer_num,const uint array_num,const int index,const double level0,const double level1=EMPTY_VALUE) { //--- Получаем значения линии индикатора со смещением (0,1) относительно переданного индекса const double value0=this.GetData(buffer_num,array_num,index); const double value1=this.GetData(buffer_num,array_num,index+1); //--- Если хоть одно из значений получить не удалось - возвращаем неопределённое значение if(value0==EMPTY_VALUE || value1==EMPTY_VALUE) return LINE_STATE_NONE; //--- Определяем второй сравниваемый уровень double level=(level1==EMPTY_VALUE ? level0 : level1); //--- Линия находится под уровнем (value1level && value0>level0) if(::NormalizeDouble(value1-level,this.m_digits)>0 && ::NormalizeDouble(value0-level0,this.m_digits)>0) return LINE_STATE_ABOVE; //--- Линия пересекла уровень снизу-вверх (value1<=level && value0>level0) if(::NormalizeDouble(value1-level,this.m_digits)<=0 && ::NormalizeDouble(value0-level0,this.m_digits)>0) return LINE_STATE_CROSS_UP; //--- Линия пересекла уровень сверху-вниз (value1>=level && value0=0 && ::NormalizeDouble(value0-level0,this.m_digits)<0) return LINE_STATE_CROSS_DOWN; //--- Линия коснулась уровня снизу (value1level0 && value0==level0) if(::NormalizeDouble(value1-level,this.m_digits)>0 && ::NormalizeDouble(value0-level0,this.m_digits)==0) return LINE_STATE_TOUCH_BELOW; //--- Линия равна значению уровня (value1==level0 && value0==level0) if(::NormalizeDouble(value1-level,this.m_digits)==0 && ::NormalizeDouble(value0-level0,this.m_digits)==0) return LINE_STATE_EQUALS; //--- Неопределённое состояние return LINE_STATE_NONE; } //+------------------------------------------------------------------+ //| Возвращает состояние линии относительно указанного уровня | //| на указанном символе/периоде графика | //+------------------------------------------------------------------+ ENUM_LINE_STATE CIndMSTF::BufferLineStateRelative(const string symbol_from,const ENUM_TIMEFRAMES timeframes_from,const int buffer_num,const uint array_num,const int index,const double level0,const double level1=EMPTY_VALUE) { //--- Определяем переданные в метод символ/период графика string symbol=(symbol_from=="" || symbol_from==NULL ? ::Symbol() : symbol_from); ENUM_TIMEFRAMES timeframe=(timeframes_from==PERIOD_CURRENT ? ::Period() : timeframes_from); //--- Получаем значения линии индикатора со смещением (0,1) относительно переданного индекса const double value0=this.GetDataTo(symbol,timeframe,buffer_num,array_num,index); const double value1=this.GetDataTo(symbol,timeframe,buffer_num,array_num,index+1); //--- Если хоть одно из значений получить не удалось - возвращаем неопределённое значение if(value0==EMPTY_VALUE || value1==EMPTY_VALUE) return LINE_STATE_NONE; //--- Определяем второй сравниваемый уровень double level=(level1==EMPTY_VALUE ? level0 : level1); //--- Линия находится под уровнем (value1level && value0>level0) if(::NormalizeDouble(value1-level,this.m_digits)>0 && ::NormalizeDouble(value0-level0,this.m_digits)>0) return LINE_STATE_ABOVE; //--- Линия пересекла уровень снизу-вверх (value1<=level && value0>level0) if(::NormalizeDouble(value1-level,this.m_digits)<=0 && ::NormalizeDouble(value0-level0,this.m_digits)>0) return LINE_STATE_CROSS_UP; //--- Линия пересекла уровень сверху-вниз (value1>=level && value0=0 && ::NormalizeDouble(value0-level0,this.m_digits)<0) return LINE_STATE_CROSS_DOWN; //--- Линия коснулась уровня снизу (value1level0 && value0==level0) if(::NormalizeDouble(value1-level,this.m_digits)>0 && ::NormalizeDouble(value0-level0,this.m_digits)==0) return LINE_STATE_TOUCH_BELOW; //--- Линия равна значению уровня (value1==level0 && value0==level0) if(::NormalizeDouble(value1-level,this.m_digits)==0 && ::NormalizeDouble(value0-level0,this.m_digits)==0) return LINE_STATE_EQUALS; //--- Неопределённое состояние return LINE_STATE_NONE; } //+------------------------------------------------------------------+ //| Возвращает описание категории | //+------------------------------------------------------------------+ string CIndMSTF::CategoryDescription(void) { //--- Создаём из перечисления ENUM_IND_CATEGORY наименование категории и возвращаем полученный текст string category=::StringSubstr(::EnumToString(this.m_category),13); if(category.Lower()) category.SetChar(0,ushort(category.GetChar(0)-0x20)); return category; } //+------------------------------------------------------------------+ //| Возвращает описание буфера индикатора | //+------------------------------------------------------------------+ string CIndMSTF::BufferDescription(const uint buffer_num) { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал и возвращаем пустую строку if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); return ""; } //--- Если у индикатора есть буферы, возвращаем описание указанного буфера, иначе - описание индикатора return(this.BuffersTotal()>0 ? this.m_buffers[buffer_num].descript : this.m_title); } //+------------------------------------------------------------------+ //| Устанавливает описание буфера индикатора | //+------------------------------------------------------------------+ void CIndMSTF::SetBufferDescription(const uint buffer_num,const string descr) { //--- Если индикатор не имеет буферов - уходим if(this.BuffersTotal()==0) return; //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал и уходим if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); return; } //--- Записываем в указанный буфер переданное в метод описание this.m_buffers[buffer_num].descript=descr; } //+------------------------------------------------------------------+ //| Отключает индексацию массивов буферов как у таймсерии | //+------------------------------------------------------------------+ void CIndMSTF::SetAsSeriesOff(void) { //--- В цикле по всем буферам индикатора отключаем флаг серийности массивов for(int i=0;i<(int)this.BuffersTotal();i++) { ::ArraySetAsSeries(this.m_buffers[i].array0,false); ::ArraySetAsSeries(this.m_buffers[i].array1,false); ::ArraySetAsSeries(this.m_buffers[i].array2,false); ::ArraySetAsSeries(this.m_buffers[i].array3,false); ::ArraySetAsSeries(this.m_buffers[i].color_indexes,false); } } //+------------------------------------------------------------------+ //| Возвращает флаг серийности указанного буфера | //+------------------------------------------------------------------+ bool CIndMSTF::IsSeries(const uint buffer_num,const uint array_num) const { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал и возвращаем false if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); return false; } //--- Возвращаем флаг серийности массива указанного буфера switch(array_num) { case 0 : return (bool)::ArrayGetAsSeries(this.m_buffers[buffer_num].array0); case 1 : return (bool)::ArrayGetAsSeries(this.m_buffers[buffer_num].array1); case 2 : return (bool)::ArrayGetAsSeries(this.m_buffers[buffer_num].array2); case 3 : return (bool)::ArrayGetAsSeries(this.m_buffers[buffer_num].array3); case 4 : return (bool)::ArrayGetAsSeries(this.m_buffers[buffer_num].color_indexes); default: break; } return false; } //+------------------------------------------------------------------+ //| Возвращает количество данных указанного буфера | //+------------------------------------------------------------------+ uint CIndMSTF::DataTotal(const uint buffer_num,const uint array_num) const { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал и возвращаем ноль if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); return 0; } //--- Возвращаем размер массива указанного буфера switch(array_num) { case 0 : return this.m_buffers[buffer_num].array0.Size(); case 1 : return this.m_buffers[buffer_num].array1.Size(); case 2 : return this.m_buffers[buffer_num].array2.Size(); case 3 : return this.m_buffers[buffer_num].array3.Size(); case 4 : return this.m_buffers[buffer_num].color_indexes.Size(); default: break; } return 0; } //+------------------------------------------------------------------+ //| Возвращает количество цветов, установленных буферу | //+------------------------------------------------------------------+ uint CIndMSTF::ColorsTotal(const uint buffer_num) const { //--- Проверяем корректность переданного в метод номера буфера и, если номер не верный, сообщаем об этом в журнал и возвращаем ноль if(buffer_num>this.BuffersTotal()-1) { string buff_limit=(this.BuffersTotal()==1 ? "0" : "0 - "+string(this.BuffersTotal()-1)); ::PrintFormat("%s: Invalid buffer number passed (%lu). Value must be %s",__FUNCTION__,buffer_num,buff_limit); return 0; } //--- Возвращаем размер массива цветов указанного буфера return this.m_buffers[buffer_num].clrs.Size(); } //+------------------------------------------------------------------+ //+------------------------------------------------------------------+ //| Класс индикатора Accelerator Oscillator | //+------------------------------------------------------------------+ class CIndAC : public CIndMSTF { public: //--- Конструктор CIndAC(const string symbol,const ENUM_TIMEFRAMES timeframe) : CIndMSTF(IND_AC,1,symbol,timeframe) { //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=(current ? "" : StringFormat("(%s)",symbol_period)); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок и категорию this.SetParameters(param); this.SetName("AC"); this.SetDescription("Accelerator Oscillator"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_WILLIAMS; this.m_digits=::Digits()+2; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_COLOR_HISTOGRAM,0); //--- Зададим для цветного буфера 0 два цвета по умолчанию this.SetBufferColorToIndex(0,0,clrGreen); this.SetBufferColorToIndex(0,1,clrRed); //--- Установим инициализирующий индекс цвета по умолчанию this.SetBufferInitColorIndex(0,0); } }; //+------------------------------------------------------------------+ //| Класс индикатора Accumulation/Distribution | //+------------------------------------------------------------------+ class CIndAD : public CIndMSTF { public: //--- Конструктор CIndAD(const string symbol,const ENUM_TIMEFRAMES timeframe, const ENUM_APPLIED_VOLUME applied_volume // используемый объем ) : CIndMSTF(IND_AD,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,1)==1) { ::ZeroMemory(this.m_param); this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=applied_volume; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=(current ? "" : StringFormat("(%s)",symbol_period)); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("A/D"); this.SetDescription("Accumulation/Distribution"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_VOLUME; this.m_digits=0; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrLightSeaGreen); } }; //+------------------------------------------------------------------+ //| Класс индикатора Average Directional Movement Index | //+------------------------------------------------------------------+ class CIndADX : public CIndMSTF { public: //--- Конструктор CIndADX(const string symbol,const ENUM_TIMEFRAMES timeframe, const int adx_period // период усреднения ) : CIndMSTF(IND_ADX,3,symbol,timeframe) { // Номера буферов: 0 - MAIN_LINE, 1 - PLUSDI_LINE, 2 - MINUSDI_LINE //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,1)==1) { ::ZeroMemory(this.m_param); this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(adx_period<1 ? 14 : adx_period); } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),adx_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("ADX"); this.SetDescription("Average Directional Movement Index"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_TREND; this.m_digits=2; //--- записываем описания буферов линий MAIN_LINE, PLUSDI_LINE и MINUSDI_LINE this.SetBufferDescription(MAIN_LINE,this.m_title); this.SetBufferDescription(PLUSDI_LINE,"+DI"); this.SetBufferDescription(MINUSDI_LINE,"-DI"); //--- Установим стиль рисования для буферов 0, 1, 2 и номера буферов данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,MAIN_LINE); this.SetBufferDrawType(1,DRAW_LINE,PLUSDI_LINE); this.SetBufferDrawType(2,DRAW_LINE,MINUSDI_LINE); //--- Зададим для буферов 0, 1 и 2 цвета по умолчанию this.SetBufferColorToIndex(MAIN_LINE,0,clrLightSeaGreen); this.SetBufferColorToIndex(PLUSDI_LINE,0,clrYellowGreen); this.SetBufferColorToIndex(MINUSDI_LINE,0,clrWheat); } }; //+------------------------------------------------------------------+ //| Класс индикатора Average Directional Movement Index Wilder | //+------------------------------------------------------------------+ class CIndADXW : public CIndMSTF { public: //--- Конструктор CIndADXW(const string symbol,const ENUM_TIMEFRAMES timeframe, const int adx_period // период усреднения ) : CIndMSTF(IND_ADXW,3,symbol,timeframe) { // Номера буферов: 0 - MAIN_LINE, 1 - PLUSDI_LINE, 2 - MINUSDI_LINE //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,1)==1) { ::ZeroMemory(this.m_param); this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(adx_period<1 ? 14 : adx_period); } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),adx_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("ADX Wilder"); this.SetDescription("Average Directional Movement Index Wilder"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_TREND; this.m_digits=2; //--- записываем описания буферов линий MAIN_LINE, PLUSDI_LINE и MINUSDI_LINE this.SetBufferDescription(MAIN_LINE,this.m_title); this.SetBufferDescription(PLUSDI_LINE,"+DI"); this.SetBufferDescription(MINUSDI_LINE,"-DI"); //--- Установим стиль рисования для буферов 0, 1, 2 и номера буферов данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,MAIN_LINE); this.SetBufferDrawType(1,DRAW_LINE,PLUSDI_LINE); this.SetBufferDrawType(2,DRAW_LINE,MINUSDI_LINE); //--- Зададим для буферов 0, 1 и 2 цвета по умолчанию this.SetBufferColorToIndex(MAIN_LINE,0,clrLightSeaGreen); this.SetBufferColorToIndex(PLUSDI_LINE,0,clrYellowGreen); this.SetBufferColorToIndex(MINUSDI_LINE,0,clrWheat); } }; //+------------------------------------------------------------------+ //| Класс индикатора Alligator | //+------------------------------------------------------------------+ class CIndAlligator : public CIndMSTF { public: //--- Конструктор CIndAlligator(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 // тип цены или handle ) : CIndMSTF(IND_ALLIGATOR,3,symbol,timeframe) { // Номера буферов: 0 - GATORJAW_LINE, 1 - GATORTEETH_LINE, 2 - GATORLIPS_LINE //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,8)==8) { ::ZeroMemory(this.m_param); //--- период для расчета челюстей this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(jaw_period<1 ? 13 : jaw_period); //--- смещение челюстей по горизонтали this.m_param[1].type=TYPE_INT; this.m_param[1].integer_value=jaw_shift; //--- период для расчета зубов this.m_param[2].type=TYPE_UINT; this.m_param[2].integer_value=(teeth_period<1 ? 8 : teeth_period); //--- смещение зубов по горизонтали this.m_param[3].type=TYPE_INT; this.m_param[3].integer_value=teeth_shift; //--- период для расчета губ this.m_param[4].type=TYPE_UINT; this.m_param[4].integer_value=(lips_period<1 ? 5 : lips_period); //--- смещение губ по горизонтали this.m_param[5].type=TYPE_INT; this.m_param[5].integer_value=lips_shift; //--- тип сглаживания this.m_param[6].type=TYPE_UINT; this.m_param[6].integer_value=ma_method; //--- тип цены или handle this.m_param[7].type=TYPE_UINT; this.m_param[7].integer_value=applied_price; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu,%lu,%lu)",symbol_period,(current ? "" : ":"),jaw_period,teeth_period,lips_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок и категорию this.SetParameters(param); this.SetName("Alligator"); this.SetDescription("Alligator"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_WILLIAMS; //--- Записываем описания буферов линий GATORJAW_LINE, GATORTEETH_LINE и GATORLIPS_LINE this.SetBufferDescription(GATORJAW_LINE,::StringFormat("Jaws(%s%lu)", (current ? "" : symbol_period+":"),jaw_period)); this.SetBufferDescription(GATORTEETH_LINE,::StringFormat("Teeth(%s%lu)",(current ? "" : symbol_period+":"),teeth_period)); this.SetBufferDescription(GATORLIPS_LINE,::StringFormat("Lips(%s%lu)", (current ? "" : symbol_period+":"),lips_period)); //--- Записываем смещения в буферы GATORJAW_LINE, GATORTEETH_LINE и GATORLIPS_LINE this.SetBufferShift(GATORJAW_LINE,jaw_shift); this.SetBufferShift(GATORTEETH_LINE,teeth_shift); this.SetBufferShift(GATORLIPS_LINE,lips_shift); //--- Установим стиль рисования для буферов 0, 1, 2 и номера буферов данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,GATORJAW_LINE); this.SetBufferDrawType(1,DRAW_LINE,GATORTEETH_LINE); this.SetBufferDrawType(2,DRAW_LINE,GATORLIPS_LINE); //--- Зададим для буферов 0, 1 и 2 цвета по умолчанию this.SetBufferColorToIndex(GATORJAW_LINE,0,clrBlue); this.SetBufferColorToIndex(GATORTEETH_LINE,0,clrRed); this.SetBufferColorToIndex(GATORLIPS_LINE,0,clrLime); } }; //+------------------------------------------------------------------+ //| Класс индикатора Adaptive Moving Average | //+------------------------------------------------------------------+ class CIndAMA : public CIndMSTF { public: //--- Конструктор CIndAMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ama_period, // период AMA const int fast_ma_period, // период быстрой скользящей const int slow_ma_period, // период медленной скользящей const int ama_shift, // смещение индикатора по горизонтали const ENUM_APPLIED_PRICE applied_price // тип цены или handle ) : CIndMSTF(IND_AMA,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,5)==5) { ::ZeroMemory(this.m_param); //--- период AMA this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(ama_period<1 ? 9 : ama_period); //--- период быстрой скользящей this.m_param[1].type=TYPE_UINT; this.m_param[1].integer_value=(fast_ma_period<1 ? 2 : fast_ma_period); //--- период медленной скользящей this.m_param[2].type=TYPE_UINT; this.m_param[2].integer_value=(slow_ma_period<1 ? 30 : slow_ma_period); //--- смещение индикатора по горизонтали this.m_param[3].type=TYPE_INT; this.m_param[3].integer_value=ama_shift; //--- тип цены или handle this.m_param[4].type=TYPE_UINT; this.m_param[4].integer_value=applied_price; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu,%lu,%lu)",symbol_period,(current ? "" : ":"),ama_period,fast_ma_period,slow_ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("AMA"); this.SetDescription("Adaptive Moving Average"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_TREND; this.m_digits=::Digits()+1; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Записываем смещение в буфер 0 this.SetBufferShift(0,ama_shift); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrRed); } }; //+------------------------------------------------------------------+ //| Класс индикатора Awesome Oscillator | //+------------------------------------------------------------------+ class CIndAO : public CIndMSTF { public: //--- Конструктор CIndAO(const string symbol,const ENUM_TIMEFRAMES timeframe) : CIndMSTF(IND_AO,1,symbol,timeframe) { //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=(current ? "" : StringFormat("(%s)",symbol_period)); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("AO"); this.SetDescription("Awesome Oscillator"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_WILLIAMS; this.m_digits=::Digits()+1; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_COLOR_HISTOGRAM,0); //--- Зададим для цветного буфера 0 два цвета по умолчанию this.SetBufferColorToIndex(0,0,clrGreen); this.SetBufferColorToIndex(0,1,clrRed); //--- Установим инициализирующий индекс цвета по умолчанию this.SetBufferInitColorIndex(0,0); } }; //+------------------------------------------------------------------+ //| Класс индикатора Average True Range | //+------------------------------------------------------------------+ class CIndATR : public CIndMSTF { public: //--- Конструктор CIndATR(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period // период усреднения ) : CIndMSTF(IND_ATR,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,1)==1) { ::ZeroMemory(this.m_param); this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(ma_period<1 ? 14 : ma_period); } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок и категорию this.SetParameters(param); this.SetName("ATR"); this.SetDescription("Average True Range"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_OSCILLATOR; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrLightSeaGreen); } }; //+------------------------------------------------------------------+ //| Класс индикатора Bears Power | //+------------------------------------------------------------------+ class CIndBears : public CIndMSTF { public: //--- Конструктор CIndBears(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period // период усреднения ) : CIndMSTF(IND_BEARS,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,1)==1) { ::ZeroMemory(this.m_param); this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(ma_period<1 ? 13 : ma_period); } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("Bears"); this.SetDescription("Bears Power"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_OSCILLATOR; this.m_digits=::Digits()+1; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_HISTOGRAM,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrSilver); } }; //+------------------------------------------------------------------+ //| Класс индикатора Bulls Power | //+------------------------------------------------------------------+ class CIndBulls : public CIndMSTF { public: //--- Конструктор CIndBulls(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period // период усреднения ) : CIndMSTF(IND_BULLS,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,1)==1) { ::ZeroMemory(this.m_param); this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(ma_period<1 ? 13 : ma_period); } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("Bulls"); this.SetDescription("Bulls Power"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_OSCILLATOR; this.m_digits=::Digits()+1; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_HISTOGRAM,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrSilver); } }; //+------------------------------------------------------------------+ //| Класс индикатора Bollinger Bands® | //+------------------------------------------------------------------+ class CIndBands : public CIndMSTF { public: //--- Конструктор CIndBands(const string symbol,const ENUM_TIMEFRAMES timeframe, const int bands_period, // период для расчета средней линии const int bands_shift, // смещение индикатора по горизонтали const double deviation, // кол-во стандартных отклонений const ENUM_APPLIED_PRICE applied_price // тип цены или handle ) : CIndMSTF(IND_BANDS,3,symbol,timeframe) { // Номера буферов: 0 - BASE_LINE, 1 - UPPER_BAND, 2 - LOWER_BAND //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,4)==4) { ::ZeroMemory(this.m_param); //--- период для расчета средней линии this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(bands_period<1 ? 20 : bands_period); //--- смещение индикатора по горизонтали this.m_param[1].type=TYPE_INT; this.m_param[1].integer_value=bands_shift; //--- кол-во стандартных отклонений this.m_param[2].type=TYPE_DOUBLE; this.m_param[2].double_value=deviation; //--- тип цены или handle this.m_param[3].type=TYPE_UINT; this.m_param[3].integer_value=applied_price; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),bands_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("Bands"); this.SetDescription("Bollinger Bands"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_TREND; this.m_digits=::Digits()+1; //---Описание буферов линий BASE_LINE, UPPER_BAND и LOWER_BAND this.SetBufferDescription(BASE_LINE,this.m_title+" Middle"); this.SetBufferDescription(UPPER_BAND,this.m_title+" Upper"); this.SetBufferDescription(LOWER_BAND,this.m_title+" Lower"); //--- Записываем смещения в буферы BASE_LINE, UPPER_BAND и LOWER_BAND this.SetBufferShift(BASE_LINE,bands_shift); this.SetBufferShift(UPPER_BAND,bands_shift); this.SetBufferShift(LOWER_BAND,bands_shift); //--- Установим стиль рисования для буферов 0, 1, 2 и номера буферов данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,BASE_LINE); this.SetBufferDrawType(1,DRAW_LINE,UPPER_BAND); this.SetBufferDrawType(2,DRAW_LINE,LOWER_BAND); //--- Зададим для буферов 0, 1 и 2 цвета по умолчанию this.SetBufferColorToIndex(BASE_LINE,0,clrMediumSeaGreen); this.SetBufferColorToIndex(UPPER_BAND,0,clrMediumSeaGreen); this.SetBufferColorToIndex(LOWER_BAND,0,clrMediumSeaGreen); } }; //+------------------------------------------------------------------+ //| Класс индикатора Commodity Channel Index | //+------------------------------------------------------------------+ class CIndCCI : public CIndMSTF { public: //--- Конструктор CIndCCI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, // период усреднения const ENUM_APPLIED_PRICE applied_price // тип цены или handle ) : CIndMSTF(IND_CCI,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,2)==2) { ::ZeroMemory(this.m_param); //--- период усреднения this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(ma_period<1 ? 14 : ma_period<2 ? 2 : ma_period); //--- тип цены или handle this.m_param[1].type=TYPE_UINT; this.m_param[1].integer_value=applied_price; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("CCI"); this.SetDescription("Commodity Channel Index"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_OSCILLATOR; this.m_digits=2; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrLightSeaGreen); } }; //+------------------------------------------------------------------+ //| Класс индикатора Chaikin Oscillator | //+------------------------------------------------------------------+ class CIndCHO : public CIndMSTF { public: //--- Конструктор CIndCHO(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 // используемый объем ) : CIndMSTF(IND_CHAIKIN,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,4)==4) { ::ZeroMemory(this.m_param); //--- быстрый период this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(fast_ma_period<1 ? 3 : fast_ma_period); //--- медленный период this.m_param[1].type=TYPE_UINT; this.m_param[1].integer_value=(slow_ma_period<1 ? 10 : slow_ma_period); //--- тип сглаживания this.m_param[2].type=TYPE_UINT; this.m_param[2].integer_value=ma_method; //--- используемый объем this.m_param[3].type=TYPE_UINT; this.m_param[3].integer_value=applied_volume; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu,%lu)",symbol_period,(current ? "" : ":"),slow_ma_period,fast_ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("CHO"); this.SetDescription("Chaikin Oscillator"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_OSCILLATOR; this.m_digits=0; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrLightSeaGreen); } }; //+------------------------------------------------------------------+ //| Класс индикатора Double Exponential Moving Average | //+------------------------------------------------------------------+ class CIndDEMA : public CIndMSTF { public: //--- Конструктор CIndDEMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, // период усреднения const int ma_shift, // смещение индикатора по горизонтали const ENUM_APPLIED_PRICE applied_price // тип цены или handle ) : CIndMSTF(IND_DEMA,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,3)==3) { ::ZeroMemory(this.m_param); //--- период усреднения this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(ma_period<1 ? 14 : ma_period); //--- смещение индикатора по горизонтали this.m_param[1].type=TYPE_INT; this.m_param[1].integer_value=ma_shift; //--- тип цены или handle this.m_param[2].type=TYPE_UINT; this.m_param[2].integer_value=applied_price; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("DEMA"); this.SetDescription("Double Exponential Moving Average"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_TREND; this.m_digits=::Digits()+1; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Записываем смещение в буфер 0 this.SetBufferShift(0,ma_shift); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrRed); } }; //+------------------------------------------------------------------+ //| Класс индикатора DeMarker | //+------------------------------------------------------------------+ class CIndDeM : public CIndMSTF { public: //--- Конструктор CIndDeM(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period // период усреднения ) : CIndMSTF(IND_DEMARKER,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,1)==1) { ::ZeroMemory(this.m_param); //--- период усреднения this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(ma_period<1 ? 14 : ma_period); } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("DeM"); this.SetDescription("DeMarker"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_OSCILLATOR; this.m_digits=3; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrLightSeaGreen); } }; //+------------------------------------------------------------------+ //| Класс индикатора Envelopes | //+------------------------------------------------------------------+ class CIndEnvelopes : public CIndMSTF { public: //--- Конструктор CIndEnvelopes(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, // тип цены или handle const double deviation // отклонение границ от средней линии ) : CIndMSTF(IND_ENVELOPES,2,symbol,timeframe) { // Номера буферов: 0 - UPPER_LINE, 1 - LOWER_LINE //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,5)==5) { ::ZeroMemory(this.m_param); //--- период для расчета средней линии this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(ma_period<1 ? 14 : ma_period); //--- смещение индикатора по горизонтали this.m_param[1].type=TYPE_INT; this.m_param[1].integer_value=ma_shift; //--- тип сглаживания this.m_param[2].type=TYPE_UINT; this.m_param[2].integer_value=ma_method; //--- тип цены или handle this.m_param[3].type=TYPE_UINT; this.m_param[3].integer_value=applied_price; //--- отклонение границ от средней линии this.m_param[4].type=TYPE_DOUBLE; this.m_param[4].double_value=deviation; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("Envelopes"); this.SetDescription("Envelopes"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_TREND; this.m_digits=::Digits()+1; //--- Описание буферов линий UPPER_LINE и LOWER_LINE this.SetBufferDescription(UPPER_LINE,this.m_title+" Upper"); this.SetBufferDescription(LOWER_LINE,this.m_title+" Lower"); //--- Записываем смещение в буферы this.SetBufferShift(0,ma_shift); this.SetBufferShift(1,ma_shift); //--- Установим стиль рисования для буферов 0, 1 и номера буферов данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,UPPER_LINE); this.SetBufferDrawType(1,DRAW_LINE,LOWER_LINE); //--- Зададим для буферов 0 и 1 цвета по умолчанию this.SetBufferColorToIndex(UPPER_LINE,0,clrBlue); this.SetBufferColorToIndex(LOWER_LINE,0,clrRed); } }; //+------------------------------------------------------------------+ //| Класс индикатора Force Index | //+------------------------------------------------------------------+ class CIndForce : public CIndMSTF { public: //--- Конструктор CIndForce(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, // период усреднения const ENUM_MA_METHOD ma_method, // тип сглаживания const ENUM_APPLIED_VOLUME applied_volume // тип объема для расчета ) : CIndMSTF(IND_FORCE,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,3)==3) { ::ZeroMemory(this.m_param); //--- период усреднения this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(ma_period<1 ? 13 : ma_period); //--- тип сглаживания this.m_param[1].type=TYPE_UINT; this.m_param[1].integer_value=ma_method; //--- тип объема для расчета this.m_param[2].type=TYPE_UINT; this.m_param[2].integer_value=applied_volume; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("Force"); this.SetDescription("Force Index"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_OSCILLATOR; this.m_digits=::Digits()+1; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrLightSeaGreen); } }; //+------------------------------------------------------------------+ //| Класс индикатора Fractals | //+------------------------------------------------------------------+ class CIndFractals : public CIndMSTF { public: //--- Конструктор CIndFractals(const string symbol,const ENUM_TIMEFRAMES timeframe) : CIndMSTF(IND_FRACTALS,2,symbol,timeframe) { // Номера буферов: 0 - UPPER_LINE, 1 - LOWER_LINE //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=(current ? "" : StringFormat("(%s)",symbol_period)); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок и категорию this.SetParameters(param); this.SetName("Fractals"); this.SetDescription("Fractals"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_WILLIAMS; //--- Описание буферов линий UPPER_LINE и LOWER_LINE this.SetBufferDescription(UPPER_LINE,this.m_title+" Up"); this.SetBufferDescription(LOWER_LINE,this.m_title+" Down"); //--- Установим стиль рисования для буферов 0, 1 и номера буферов данных расчётной части this.SetBufferDrawType(0,DRAW_ARROW,UPPER_LINE); this.SetBufferDrawType(1,DRAW_ARROW,LOWER_LINE); //--- Зададим для буферов 0 и 1 цвета по умолчанию this.SetBufferColorToIndex(UPPER_LINE,0,clrGray); this.SetBufferColorToIndex(LOWER_LINE,0,clrGray); //--- Устанавливаем количество баров, необходимое для расчёта индикатора на текущем тике this.SetBarsToCalculate(3); } }; //+------------------------------------------------------------------+ //| Класс индикатора Fractal Adaptive Moving Average | //+------------------------------------------------------------------+ class CIndFrAMA : public CIndMSTF { public: //--- Конструктор CIndFrAMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, // период усреднения const int ma_shift, // смещение индикатора по горизонтали const ENUM_APPLIED_PRICE applied_price // тип цены или handle ) : CIndMSTF(IND_FRAMA,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,3)==3) { ::ZeroMemory(this.m_param); //--- период усреднения this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(ma_period<1 ? 14 : ma_period); //--- смещение индикатора по горизонтали this.m_param[1].type=TYPE_INT; this.m_param[1].integer_value=ma_shift; //--- тип цены или handle this.m_param[2].type=TYPE_UINT; this.m_param[2].integer_value=applied_price; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("FRAMA"); this.SetDescription("Fractal Adaptive Moving Average"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_TREND; this.m_digits=::Digits()+1; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Записываем смещение в буфер 0 this.SetBufferShift(0,ma_shift); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrBlue); } }; //+------------------------------------------------------------------+ //| Класс индикатора Gator Oscillator | //+------------------------------------------------------------------+ class CIndGator : public CIndMSTF { public: //--- Конструктор CIndGator(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 // тип цены или handle ) : CIndMSTF(IND_GATOR,2,symbol,timeframe) { // Номера буферов: 0 - UPPER_HISTOGRAM, 1- цветовой буфер верхней гистограммы, 2 - LOWER_HISTOGRAM, 3- цветовой буфер нижней гистограммы //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,8)==8) { ::ZeroMemory(this.m_param); //--- период для расчета челюстей this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(jaw_period<1 ? 13 : jaw_period); //--- смещение челюстей по горизонтали this.m_param[1].type=TYPE_INT; this.m_param[1].integer_value=jaw_shift; //--- период для расчета зубов this.m_param[2].type=TYPE_UINT; this.m_param[2].integer_value=(teeth_period<1 ? 8 : teeth_period); //--- смещение зубов по горизонтали this.m_param[3].type=TYPE_INT; this.m_param[3].integer_value=teeth_shift; //--- период для расчета губ this.m_param[4].type=TYPE_UINT; this.m_param[4].integer_value=(lips_period<1 ? 5 : lips_period); //--- смещение губ по горизонтали this.m_param[5].type=TYPE_INT; this.m_param[5].integer_value=lips_shift; //--- тип сглаживания this.m_param[6].type=TYPE_UINT; this.m_param[6].integer_value=ma_method; //--- тип цены или handle this.m_param[7].type=TYPE_UINT; this.m_param[7].integer_value=applied_price; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu,%lu,%lu)",symbol_period,(current ? "" : ":"),jaw_period,teeth_period,lips_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("Gator"); this.SetDescription("Gator Oscillator"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_WILLIAMS; this.m_digits=::Digits()+1; //--- Описание буферов линий UPPER_HISTOGRAM, буфер цвета верхней гистограммы, LOWER_HISTOGRAM и буфер цвета нижней гистограммы this.SetBufferDescription(0,this.m_title+" Up"); this.SetBufferDescription(1,this.m_title+" Down"); //--- Записываем смещения в буферы UPPER_HISTOGRAM, 1, LOWER_HISTOGRAM и 2 this.SetBufferShift(0,teeth_shift); this.SetBufferShift(1,lips_shift); //--- Установим стиль рисования для буферов 0, 1 и номера буферов данных расчётной части this.SetBufferDrawType(0,DRAW_COLOR_HISTOGRAM,UPPER_HISTOGRAM); this.SetBufferDrawType(1,DRAW_COLOR_HISTOGRAM,LOWER_HISTOGRAM); //--- Зададим для цветных буферов цвета по умолчанию this.SetBufferColorToIndex(0,0,clrGreen); this.SetBufferColorToIndex(0,1,clrRed); this.SetBufferColorToIndex(1,0,clrGreen); this.SetBufferColorToIndex(1,1,clrRed); //--- Установим инициализирующий индекс цвета по умолчанию this.SetBufferInitColorIndex(0,0); this.SetBufferInitColorIndex(1,0); } }; //+------------------------------------------------------------------+ //| Класс индикатора Ichimoku Kinko Hyo | //+------------------------------------------------------------------+ class CIndIchimoku : public CIndMSTF { public: //--- Конструктор CIndIchimoku(const string symbol,const ENUM_TIMEFRAMES timeframe, const int tenkan_sen, // период Tenkan-sen const int kijun_sen, // период Kijun-sen const int senkou_span_b // период Senkou Span B ) : CIndMSTF(IND_ICHIMOKU,5,symbol,timeframe) { // Номера буферов: 0 - TENKANSEN_LINE, 1 - KIJUNSEN_LINE, 2 - SENKOUSPANA_LINE, 3 - SENKOUSPANB_LINE, 4 - CHIKOUSPAN_LINE //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,3)==3) { ::ZeroMemory(this.m_param); //--- период Tenkan-sen this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(tenkan_sen<1 ? 9 : tenkan_sen); //--- период Kijun-sen this.m_param[1].type=TYPE_UINT; this.m_param[1].integer_value=(kijun_sen<1 ? 26 : kijun_sen); //--- период Senkou Span B this.m_param[2].type=TYPE_UINT; this.m_param[2].integer_value=(senkou_span_b<1 ? 52 : senkou_span_b); } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu,%lu,%lu)",symbol_period,(current ? "" : ":"),tenkan_sen,kijun_sen,senkou_span_b); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("Ichimoku"); this.SetDescription("Ichimoku Kinko Hyo"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_TREND; this.m_digits=::Digits()+1; //--- Описание буферов линий TENKANSEN_LINE, KIJUNSEN_LINE, SENKOUSPANA_LINE, SENKOUSPANB_LINE и CHIKOUSPAN_LINE this.SetBufferDescription(TENKANSEN_LINE,::StringFormat("Tenkan-sen(%lu)",tenkan_sen)); this.SetBufferDescription(KIJUNSEN_LINE,::StringFormat("Kijun-sen(%lu)",kijun_sen)); this.SetBufferDescription(SENKOUSPANA_LINE,"Senkou Span A"); this.SetBufferDescription(SENKOUSPANB_LINE,::StringFormat("Senkou Span B(%lu)",senkou_span_b)); this.SetBufferDescription(CHIKOUSPAN_LINE,"Chikou Span"); //--- Записываем смещения в буферы SENKOUSPANA_LINE, SENKOUSPANB_LINE и CHIKOUSPAN_LINE //this.SetBufferShift(SENKOUSPANA_LINE,kijun_sen); //this.SetBufferShift(SENKOUSPANB_LINE,kijun_sen); //this.SetBufferShift(CHIKOUSPAN_LINE,kijun_sen-senkou_span_b); } }; //+------------------------------------------------------------------+ //| Класс индикатора Market Facilitation Index | //+------------------------------------------------------------------+ class CIndBWMFI : public CIndMSTF { public: //--- Конструктор CIndBWMFI(const string symbol,const ENUM_TIMEFRAMES timeframe, const ENUM_APPLIED_VOLUME applied_volume // тип объема для расчета ) : CIndMSTF(IND_BWMFI,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,1)==1) { ::ZeroMemory(this.m_param); //--- тип объема для расчета this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=applied_volume; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=(current ? "" : StringFormat("(%s)",symbol_period)); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок и категорию this.SetParameters(param); this.SetName("BW MFI"); this.SetDescription("Market Facilitation Index"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_WILLIAMS; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_COLOR_HISTOGRAM,0); //--- Зададим для цветного буфера 0 четыре цвета по умолчанию this.SetBufferColorToIndex(0,0,clrLime); this.SetBufferColorToIndex(0,1,clrSaddleBrown); this.SetBufferColorToIndex(0,2,clrBlue); this.SetBufferColorToIndex(0,3,clrPink); //--- Установим инициализирующий индекс цвета по умолчанию this.SetBufferInitColorIndex(0,0); } }; //+------------------------------------------------------------------+ //| Класс индикатора Momentum | //+------------------------------------------------------------------+ class CIndMomentum : public CIndMSTF { public: //--- Конструктор CIndMomentum(const string symbol,const ENUM_TIMEFRAMES timeframe, const int mom_period, // период усреднения const ENUM_APPLIED_PRICE applied_price // тип цены или handle ) : CIndMSTF(IND_MOMENTUM,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,2)==2) { ::ZeroMemory(this.m_param); //--- период усреднения this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(mom_period<1 ? 14 : mom_period); //--- тип цены или handle this.m_param[1].type=TYPE_UINT; this.m_param[1].integer_value=applied_price; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),mom_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("Momentum"); this.SetDescription("Momentum"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_OSCILLATOR; this.m_digits=2; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrDodgerBlue); } }; //+------------------------------------------------------------------+ //| Класс индикатора Money Flow Index | //+------------------------------------------------------------------+ class CIndMFI : public CIndMSTF { public: //--- Конструктор CIndMFI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, // период усреднения const ENUM_APPLIED_VOLUME applied_volume // тип объема для расчета ) : CIndMSTF(IND_MFI,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,2)==2) { ::ZeroMemory(this.m_param); //--- период усреднения this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(ma_period<1 ? 14 : ma_period); //--- тип объема для расчета this.m_param[1].type=TYPE_UINT; this.m_param[1].integer_value=applied_volume; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок и категорию this.SetParameters(param); this.SetName("MFI"); this.SetDescription("Money Flow Index"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_VOLUME; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrDodgerBlue); } }; //+------------------------------------------------------------------+ //| Класс индикатора Moving Average | //+------------------------------------------------------------------+ class CIndMA : public CIndMSTF { public: //--- Конструктор CIndMA(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 // тип цены или handle ) : CIndMSTF(IND_MA,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,4)==4) { ::ZeroMemory(this.m_param); //--- период усреднения this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(ma_period<1 ? 10 : ma_period); //--- смещение индикатора по горизонтали this.m_param[1].type=TYPE_INT; this.m_param[1].integer_value=ma_shift; //--- тип сглаживания this.m_param[2].type=TYPE_UINT; this.m_param[2].integer_value=ma_method; //--- тип цены или handle this.m_param[3].type=TYPE_UINT; this.m_param[3].integer_value=applied_price; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("MA"); this.SetDescription("Moving Average"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_TREND; this.m_digits=::Digits()+1; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Записываем смещение в буфер 0 this.SetBufferShift(0,ma_shift); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrRed); } }; //+------------------------------------------------------------------+ //| Класс индикатора Moving Average of Oscillator | //+------------------------------------------------------------------+ class CIndOsMA : public CIndMSTF { public: //--- Конструктор CIndOsMA(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 // тип цены или handle ) : CIndMSTF(IND_OSMA,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,4)==4) { ::ZeroMemory(this.m_param); //--- период быстрой средней this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(fast_ema_period<1 ? 12 : fast_ema_period); //--- период медленной средней this.m_param[1].type=TYPE_UINT; this.m_param[1].integer_value=(slow_ema_period<1 ? 26 : slow_ema_period); //--- период усреднения разности this.m_param[2].type=TYPE_UINT; this.m_param[2].integer_value=(signal_period<1 ? 9 : signal_period<2 ? 2 : signal_period); //--- тип цены или handle this.m_param[3].type=TYPE_UINT; this.m_param[3].integer_value=applied_price; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu,%lu,%lu)",symbol_period,(current ? "" : ":"),fast_ema_period,slow_ema_period,signal_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("OsMA"); this.SetDescription("Moving Average of Oscillator"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_OSCILLATOR; this.m_digits=::Digits()+2; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_HISTOGRAM,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrSilver); } }; //+------------------------------------------------------------------+ //| Класс индикатора Moving Averages Convergence/Divergence | //+------------------------------------------------------------------+ class CIndMACD : public CIndMSTF { public: //--- Конструктор CIndMACD(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 // тип цены или handle ) : CIndMSTF(IND_MACD,2,symbol,timeframe) { // Номера буферов: 0 - MAIN_LINE, 1 - SIGNAL_LINE //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,4)==4) { ::ZeroMemory(this.m_param); //--- период быстрой средней this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(fast_ema_period<1 ? 12 : fast_ema_period); //--- период медленной средней this.m_param[1].type=TYPE_UINT; this.m_param[1].integer_value=(slow_ema_period<1 ? 26 : slow_ema_period); //--- период усреднения разности this.m_param[2].type=TYPE_UINT; this.m_param[2].integer_value=(signal_period<1 ? 9 : signal_period); //--- тип цены или handle this.m_param[3].type=TYPE_UINT; this.m_param[3].integer_value=applied_price; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu,%lu,%lu)",symbol_period,(current ? "" : ":"),fast_ema_period,slow_ema_period,signal_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("MACD"); this.SetDescription("Moving Averages Convergence/Divergence"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_OSCILLATOR; this.m_digits=::Digits()+1; //--- Описание буферов линии MAIN_LINE и SIGNAL_LINE this.SetBufferDescription(MAIN_LINE,this.m_title); this.SetBufferDescription(SIGNAL_LINE,"Signal"); //--- Установим стиль рисования для буферов 0, 1 и номера буферов данных расчётной части this.SetBufferDrawType(0,DRAW_HISTOGRAM,MAIN_LINE); this.SetBufferDrawType(1,DRAW_LINE,SIGNAL_LINE); //--- Зададим для буферов 0 и 1 цвета по умолчанию this.SetBufferColorToIndex(MAIN_LINE,0,clrSilver); this.SetBufferColorToIndex(SIGNAL_LINE,0,clrRed); } }; //+------------------------------------------------------------------+ //| Класс индикатора On Balance Volume | //+------------------------------------------------------------------+ class CIndOBV : public CIndMSTF { public: //--- Конструктор CIndOBV(const string symbol,const ENUM_TIMEFRAMES timeframe, const ENUM_APPLIED_VOLUME applied_volume // тип объема для расчета ) : CIndMSTF(IND_OBV,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,1)==1) { ::ZeroMemory(this.m_param); //--- тип объема для расчета this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=applied_volume; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=(current ? "" : StringFormat("(%s)",symbol_period)); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("OBV"); this.SetDescription("On Balance Volume"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_VOLUME; this.m_digits=0; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrLightSeaGreen); } }; //+------------------------------------------------------------------+ //| Класс индикатора Parabolic Stop and Reverse system | //+------------------------------------------------------------------+ class CIndSAR : public CIndMSTF { public: //--- Конструктор CIndSAR(const string symbol,const ENUM_TIMEFRAMES timeframe, const double step, // шаг изменения цены - коэффициент ускорения const double maximum // максимальный шаг ) : CIndMSTF(IND_SAR,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,2)==2) { ::ZeroMemory(this.m_param); //--- шаг изменения цены - коэффициент ускорения this.m_param[0].type=TYPE_DOUBLE; this.m_param[0].double_value=step; //--- максимальный шаг this.m_param[1].type=TYPE_DOUBLE; this.m_param[1].double_value=maximum; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%.2f,%.2f)",symbol_period,(current ? "" : ":"),step,maximum); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок и категорию this.SetParameters(param); this.SetName("SAR"); this.SetDescription("Parabolic SAR"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_TREND; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_ARROW,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrLime); } }; //+------------------------------------------------------------------+ //| Класс индикатора Relative Strength Index | //+------------------------------------------------------------------+ class CIndRSI : public CIndMSTF { public: //--- Конструктор CIndRSI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, // период усреднения const ENUM_APPLIED_PRICE applied_price // тип цены или handle ) : CIndMSTF(IND_RSI,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,2)==2) { ::ZeroMemory(this.m_param); //--- период усреднения this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(ma_period<1 ? 14 : ma_period<2 ? 2 : ma_period); //--- тип цены или handle this.m_param[1].type=TYPE_UINT; this.m_param[1].integer_value=applied_price; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("RSI"); this.SetDescription("Relative Strength Index"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_OSCILLATOR; this.m_digits=2; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrDodgerBlue); } }; //+------------------------------------------------------------------+ //| Класс индикатора Relative Vigor Index | //+------------------------------------------------------------------+ class CIndRVI : public CIndMSTF { public: //--- Конструктор CIndRVI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period // период усреднения ) : CIndMSTF(IND_RVI,2,symbol,timeframe) { // Номера буферов: 0 - MAIN_LINE, 1 - SIGNAL_LINE //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,1)==1) { ::ZeroMemory(this.m_param); //--- период усреднения this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(ma_period<1 ? 10 : ma_period); } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("RVI"); this.SetDescription("Relative Vigor Index"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_OSCILLATOR; this.m_digits=3; //--- Описание буферов линии MAIN_LINE и SIGNAL_LINE this.SetBufferDescription(MAIN_LINE,this.m_title); this.SetBufferDescription(SIGNAL_LINE,"Signal"); //--- Установим стиль рисования для буферов 0, 1 и номера буферов данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,MAIN_LINE); this.SetBufferDrawType(1,DRAW_LINE,SIGNAL_LINE); //--- Зададим для буферов 0 и 1 цвета по умолчанию this.SetBufferColorToIndex(MAIN_LINE,0,clrGreen); this.SetBufferColorToIndex(SIGNAL_LINE,0,clrRed); } }; //+------------------------------------------------------------------+ //| Класс индикатора Standard Deviation | //+------------------------------------------------------------------+ class CIndStdDev : public CIndMSTF { public: //--- Конструктор CIndStdDev(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 // тип цены или handle ) : CIndMSTF(IND_STDDEV,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,4)==4) { ::ZeroMemory(this.m_param); //--- период усреднения this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(ma_period<1 ? 20 : ma_period<2 ? 2 : ma_period); //--- смещение индикатора по горизонтали this.m_param[1].type=TYPE_INT; this.m_param[1].integer_value=ma_shift; //--- тип сглаживания this.m_param[2].type=TYPE_UINT; this.m_param[2].integer_value=ma_method; //--- тип цены или handle this.m_param[3].type=TYPE_UINT; this.m_param[3].integer_value=applied_price; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("StdDev"); this.SetDescription("Standard Deviation"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_TREND; this.m_digits=::Digits()+1; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Записываем смещение в буфер 0 this.SetBufferShift(0,ma_shift); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrMediumSeaGreen); } }; //+------------------------------------------------------------------+ //| Класс индикатора Stochastic Oscillator | //+------------------------------------------------------------------+ class CIndStoch : public CIndMSTF { public: //--- Конструктор CIndStoch(const string symbol,const ENUM_TIMEFRAMES timeframe, const int Kperiod, // K-период (количество баров для расчетов) const int Dperiod, // D-период (период первичного сглаживания) const int slowing, // окончательное сглаживание const ENUM_MA_METHOD ma_method, // тип сглаживания const ENUM_STO_PRICE price_field // способ расчета стохастика ) : CIndMSTF(IND_STOCHASTIC,2,symbol,timeframe) { // Номера буферов: 0 - MAIN_LINE, 1 - SIGNAL_LINE //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,5)==5) { ::ZeroMemory(this.m_param); //--- K-период (количество баров для расчетов) this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(Kperiod<1 ? 5 : Kperiod); //--- D-период (период первичного сглаживания) this.m_param[1].type=TYPE_UINT; this.m_param[1].integer_value=(Dperiod<1 ? 3 : Dperiod); //--- окончательное сглаживание this.m_param[2].type=TYPE_UINT; this.m_param[2].integer_value=(slowing<1 ? 3 : slowing); //--- тип сглаживания this.m_param[3].type=TYPE_UINT; this.m_param[3].integer_value=ma_method; //--- способ расчета стохастика this.m_param[4].type=TYPE_UINT; this.m_param[4].integer_value=price_field; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu,%lu,%lu)",symbol_period,(current ? "" : ":"),Kperiod,Dperiod,slowing); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("Stoch"); this.SetDescription("Stochastic Oscillator"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_OSCILLATOR; this.m_digits=2; //--- Описание буферов линии MAIN_LINE и SIGNAL_LINE this.SetBufferDescription(MAIN_LINE,this.m_title); this.SetBufferDescription(SIGNAL_LINE,"Signal"); //--- Установим стиль рисования для буферов 0, 1 и номера буферов данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,MAIN_LINE); this.SetBufferDrawType(1,DRAW_LINE,SIGNAL_LINE); //--- Зададим для буферов 0 и 1 цвета по умолчанию this.SetBufferColorToIndex(MAIN_LINE,0,clrLightSeaGreen); this.SetBufferColorToIndex(SIGNAL_LINE,0,clrRed); } }; //+------------------------------------------------------------------+ //| Класс индикатора Triple Exponential Moving Average | //+------------------------------------------------------------------+ class CIndTEMA : public CIndMSTF { public: //--- Конструктор CIndTEMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, // период усреднения const int ma_shift, // смещение индикатора по горизонтали const ENUM_APPLIED_PRICE applied_price // тип цены или handle ) : CIndMSTF(IND_TEMA,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,3)==3) { ::ZeroMemory(this.m_param); //--- период усреднения this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(ma_period<1 ? 14 : ma_period); //--- смещение индикатора по горизонтали this.m_param[1].type=TYPE_INT; this.m_param[1].integer_value=ma_shift; //--- тип цены или handle this.m_param[2].type=TYPE_UINT; this.m_param[2].integer_value=applied_price; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("TEMA"); this.SetDescription("Triple Exponential Moving Average"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_TREND; this.m_digits=::Digits()+1; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Записываем смещение в буфер 0 this.SetBufferShift(0,ma_shift); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrRed); } }; //+------------------------------------------------------------------+ //| Класс индикатора Triple Exponential Moving Averages Oscillator | //+------------------------------------------------------------------+ class CIndTriX : public CIndMSTF { public: //--- Конструктор CIndTriX(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period, // период усреднения const ENUM_APPLIED_PRICE applied_price // тип цены или handle ) : CIndMSTF(IND_TRIX,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,2)==2) { ::ZeroMemory(this.m_param); //--- период усреднения this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(ma_period<1 ? 14 : ma_period<2 ? 2 : ma_period); //--- тип цены или handle this.m_param[1].type=TYPE_UINT; this.m_param[1].integer_value=applied_price; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),ma_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок и категорию this.SetParameters(param); this.SetName("TRIX"); this.SetDescription("Triple Exponential Average"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_OSCILLATOR; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrRed); } }; //+------------------------------------------------------------------+ //| Класс индикатора Larry Williams' Percent Range | //+------------------------------------------------------------------+ class CIndWPR : public CIndMSTF { public: //--- Конструктор CIndWPR(const string symbol,const ENUM_TIMEFRAMES timeframe, const int calc_period // период усреднения ) : CIndMSTF(IND_WPR,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,1)==1) { ::ZeroMemory(this.m_param); //--- период усреднения this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(calc_period<1 ? 14 : calc_period); } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu)",symbol_period,(current ? "" : ":"),calc_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("%R"); this.SetDescription("Williams' Percent Range"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_OSCILLATOR; this.m_digits=2; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrAqua); } }; //+------------------------------------------------------------------+ //| Класс индикатора Variable Index Dynamic Average | //+------------------------------------------------------------------+ class CIndVIDyA : public CIndMSTF { public: //--- Конструктор CIndVIDyA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int cmo_period, // период Chande Momentum const int ema_period, // период фактора сглаживания const int ma_shift, // смещение индикатора по горизонтали const ENUM_APPLIED_PRICE applied_price // тип цены или handle ) : CIndMSTF(IND_VIDYA,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,4)==4) { ::ZeroMemory(this.m_param); //--- период Chande Momentum this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=(cmo_period<1 ? 9 : cmo_period); //--- период фактора сглаживания this.m_param[1].type=TYPE_UINT; this.m_param[1].integer_value=(ema_period<1 ? 12 : ema_period); //--- смещение индикатора по горизонтали this.m_param[2].type=TYPE_INT; this.m_param[2].integer_value=ma_shift; //--- тип цены или handle this.m_param[3].type=TYPE_UINT; this.m_param[3].integer_value=applied_price; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=StringFormat("(%s%s%lu,%lu)",symbol_period,(current ? "" : ":"),cmo_period,ema_period); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("VIDYA"); this.SetDescription("Variable Index Dynamic Average"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_TREND; this.m_digits=::Digits()+1; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Записываем смещение в буфер 0 this.SetBufferShift(0,ma_shift); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_LINE,0); //--- Зададим для буфера 0 цвет по умолчанию this.SetBufferColorToIndex(0,0,clrRed); } }; //+------------------------------------------------------------------+ //| Класс индикатора Volumes | //+------------------------------------------------------------------+ class CIndVolumes : public CIndMSTF { public: //--- Конструктор CIndVolumes(const string symbol,const ENUM_TIMEFRAMES timeframe, const ENUM_APPLIED_VOLUME applied_volume // тип объема ) : CIndMSTF(IND_VOLUMES,1,symbol,timeframe) { //--- Устанавливаем размер массива параметров и заполняем его ::ResetLastError(); if(::ArrayResize(this.m_param,1)==1) { ::ZeroMemory(this.m_param); //--- тип объема this.m_param[0].type=TYPE_UINT; this.m_param[0].integer_value=applied_volume; } else ::PrintFormat("%s: ArrayResize failed. Error %ld",__FUNCTION__,::GetLastError()); //--- Создаём описание параметров. //--- Если символ или период графика не текущие, то к параметрам добавляются их описания bool current=(this.Symbol()==::Symbol() && this.Timeframe()==::Period()); string symbol_period=(current ? "" : ::StringFormat("%s,%s",this.Symbol(),this.TimeframeDescription())); string param=(current ? "" : StringFormat("(%s)",symbol_period)); //--- Записываем описание параметров, наименование индикатора, его описание, заголовок, категорию и Digits индикатора this.SetParameters(param); this.SetName("Volumes"); this.SetDescription("Volumes"); this.m_title=this.Name()+this.Parameters(); this.m_category=IND_CATEGORY_VOLUME; this.m_digits=0; //--- Записываем описание буфера линии this.SetBufferDescription(0,this.m_title); //--- Установим стиль рисования для буфера 0 и номер буфера данных расчётной части this.SetBufferDrawType(0,DRAW_COLOR_HISTOGRAM,0); //--- Зададим для цветного буфера 0 два цвета по умолчанию this.SetBufferColorToIndex(0,0,clrGreen); this.SetBufferColorToIndex(0,1,clrRed); //--- Установим инициализирующий индекс цвета по умолчанию this.SetBufferInitColorIndex(0,0); } }; //+------------------------------------------------------------------+ //| Класс пользовательского индикатора | //+------------------------------------------------------------------+ class CIndCustom : public CIndMSTF { public: //--- Конструктор CIndCustom(const string symbol,const ENUM_TIMEFRAMES timeframe, const string path, // путь к индикатору (например, "Examples\\MACD.ex5") const string name, // имя пользовательского индикатора const uint buffers, // количество буферов индикатора const uint bars_to_calculate, // количество баров, необходимое для расчёта индикатора на текущем тике const MqlParam ¶m[] // массив параметров пользовательского индикатора ) : CIndMSTF(IND_CUSTOM,buffers,symbol,timeframe) { //--- Если передан пустой массив параметров - сообщаем об этом в журнал int total=(int)param.Size(); if(total==0) ::PrintFormat("%s Error. Passed an empty array",__FUNCTION__); //--- Если массив не пустой и его размер увеличен на 1 (в первый параметр типа string должно быть записано имя индикатора) ResetLastError(); if(total>0 && ::ArrayResize(this.m_param,total+1)==total+1) { //--- Обнуляем данные в массиве и вписываем имя (путь к файлу и имя .ex5 файла) ::ZeroMemory(this.m_param); //--- имя пользовательского индикатора this.m_param[0].type=TYPE_STRING; this.m_param[0].string_value=path; //--- заполняем массив параметров индикатора for(int i=0;i class CMSTFIndicators { private: CArrayObj m_list; //--- Создаёт индикатор для переданного объекта bool CreateIndicator(CIndMSTF *ind_obj); //--- Добавляет указанный индикатор в коллекцию int AddNewIndicator(CIndMSTF *ind_obj,const string source); public: //--- Возвращает (1) объект индикатора по хэндлу, (2) количество индикаторов в коллекции CIndMSTF *GetIndicatorObj(const int ind_handle,const string source) const; uint IndicatorsTotal(void) const { return this.m_list.Total(); } //--- Заполняет данными буферы (1) индикатора по хэндлу, (2) всех индикаторов в коллекции bool Calculate(const int ind_handle); bool Calculate(void); //--- Устанавливает (1) указанное, (2) по умолчанию описание, (3) цвета линии буфера индикатора void SetPlotLabel(const uint plot_index,const string descript); void SetPlotLabelFromBuffer(const uint plot_index,const int ind_handle,const uint buffer_num); void SetPlotColorsFromBuffer(const uint plot_index,const int ind_handle,const uint buffer_num); //--- Устанавливает смещение указанному рисуемому буферу void SetPlotShift(const uint plot_index,const int shift); //--- (1) Устанавливает (2) возвращает инициализирующее значение указанного буфера указанного по хэндлу индикатора void SetBufferInitValue(const int ind_handle,const uint buffer_num,const double value); double BufferInitValue(const int ind_handle,const uint buffer_num) const; //--- (1) Устанавливает (2) возвращает инициализирующее значение индекса цвета для указанного буфера void SetBufferInitColorIndex(const int ind_handle,const uint buffer_num,const uchar index); uchar BufferInitColorIndex(const int ind_handle,const uint buffer_num) const; //--- (1) Устанавливает, (2) возвращает значение цвета по индексу для указанного буфера void SetBufferColorToIndex(const int ind_handle,const uint buffer_num,const uchar color_idx,const color clr); color BufferColorByIndex(const int ind_handle,const uint buffer_num,const uchar color_idx) const; //--- Возвращает флаг цветного буфера bool IsColoredBuffer(const int ind_handle,const uint buffer_num) const; //--- Возвращает данные индикатора по хэндлу из указанного буфера по индексу (1) как есть, (2) на указанный символ/таймфрейм double GetData(const int ind_handle,const uint buffer_num,const uint array_num,const uint index); double GetDataTo(const string symbol_to,const ENUM_TIMEFRAMES timeframe_to,const int ind_handle,const uint buffer_num,const uint array_num,const uint index); //--- Возвращает данные индексов цвета индикатора по хэндлу из указанного буфера по индексу (1) как есть, (2) на указанный символ/таймфрейм double GetColorData(const int ind_handle,const uint buffer_num,const uint index); double GetColorDataTo(const string symbol_to,const ENUM_TIMEFRAMES timeframe_to,const int ind_handle,const uint buffer_num,const uint index); //--- (1) Копирует данные указанного буфера расчётной части указанного по хэндлу индикатора в буфер индикатора с учётом символа/периода графика, //--- (2) Копирует данные указанного цветного буфера расчётной части указанного по хэндлу индикатора в цветной буфер индикатора с учётом символа/периода графика, //--- (2) возвращает количество данных в укакзанном буфере указанного по хэндлу индикатора bool DataToBuffer(const string symbol_to,const ENUM_TIMEFRAMES timeframe_to,const int ind_handle,const uint buffer_num,const uint array_num,const int limit,double &buffer[]); bool DataToColorBuffer(const string symbol_to,const ENUM_TIMEFRAMES timeframe_to,const int ind_handle,const uint buffer_num,const uint array_num,const int limit,double &plot_buffer[],double &color_buffer[]); uint DataTotal(const int ind_handle,const uint buffer_num) const; //--- Возвращает (1) описание буфера, (2) состояние данных линии указанного буфера указанного по хэндлу индикатора на указанном баре //--- (3) состояние линии индикатора с учётом символа/периода графика, (4) состояние отношения линии индикатора с указанным уровнем, //--- (5) состояние отношения линии индикатора с указанным уровнем с учётом символа/периода графика, (6) описание категории индикатора string BufferDescription(const int ind_handle,const uint buffer_num); ENUM_LINE_STATE BufferLineState(const int ind_handle,const uint buffer_num,const uint array_num,const int index); ENUM_LINE_STATE BufferLineState(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ind_handle,const uint buffer_num,const uint array_num,const int index); ENUM_LINE_STATE BufferLineStateRelative(const int ind_handle,const int buffer_num,const uint array_num,const int index,const double level0,const double level1=EMPTY_VALUE); ENUM_LINE_STATE BufferLineStateRelative(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ind_handle,const int buffer_num,const uint array_num,const int index,const double level0,const double level1=EMPTY_VALUE); string CategoryDescription(const int ind_handle); //--- Устанавливает (1) идентификатор, (2) Digits, (3) пользовательское описание, (4) описание буфера void SetID(const int ind_handle,const int id); void SetDigits(const int ind_handle,const int digits); void SetDescription(const int ind_handle,const string descr); void SetBufferDescription(const int ind_handle,const uint buffer_num,const string descr); //--- Возвращает флаг серийности указанного буфера, (2) синхронизированности исторических данных по символу/периоду bool IsSeries(const int ind_handle,const uint buffer_num,const uint array_num) const; bool IsSynchronized(const int ind_handle) const; //--- Возвращает (1) таймфрейм, (2) символ, (3) наименование, (4) список параметров, (5) хэндл, (6) Digits //--- количество (7) буферов, (8) баров, (9) идентификатор, (10) описание, (11) заголовок, (12) категорию, //--- (13) количество параметрпов, (14) тип программы, описание (15) категории, (16) буфера индикатора ENUM_TIMEFRAMES Timeframe(const int ind_handle) const; string Symbol(const int ind_handle) const; string Name(const int ind_handle) const; string Parameters(const int ind_handle) const; int Digits(const int ind_handle) const; uint BuffersTotal(const int ind_handle) const; uint RatesTotal(const int ind_handle) const; int ID(const int ind_handle) const; string Description(const int ind_handle) const; string Title(const int ind_handle) const; ENUM_IND_CATEGORY Category(const int ind_handle) const; uint ParamsTotal(const int ind_handle) const; //--- Возвращает (1) структуру параметров по индексу из массива, (2) описание таймфрейма MqlParam GetMqlParam(const int ind_handle,const int index) const; string TimeframeDescription(const int ind_handle) const; //--- Возвращает количество рассчитанных данных int Calculated(const int ind_handle) const; //--- Виртуальный метод, возвращающий тип объекта (индикатора) ENUM_INDICATOR Type(const int ind_handle) const; //--- Методы добавления индикаторов в коллекцию int AddNewAC(const string symbol,const ENUM_TIMEFRAMES timeframe); int AddNewAD(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK); int AddNewADX(const string symbol,const ENUM_TIMEFRAMES timeframe,const int adx_period=14); int AddNewADXWilder(const string symbol,const ENUM_TIMEFRAMES timeframe,const int adx_period=14); int AddNewAlligator(const string symbol,const ENUM_TIMEFRAMES timeframe,const int jaw_period=13, const int jaw_shift=8, const int teeth_period=8, const int teeth_shift=5, const int lips_period=5, const int lips_shift=3, const ENUM_MA_METHOD ma_method=MODE_SMMA, const ENUM_APPLIED_PRICE applied_price=PRICE_MEDIAN); int AddNewAMA(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ama_period=9, const int fast_ma_period=2, const int slow_ma_period=30, const int ama_shift=0, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE); int AddNewAO(const string symbol,const ENUM_TIMEFRAMES timeframe); int AddNewATR(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=14); int AddNewBearsPower(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=13); int AddNewBullsPower(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=13); int AddNewBands(const string symbol,const ENUM_TIMEFRAMES timeframe,const int bands_period=20, const int bands_shift=0, const double deviation=2.0, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE); int AddNewCCI(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=14, const ENUM_APPLIED_PRICE applied_price=PRICE_TYPICAL); int AddNewChaikin(const string symbol,const ENUM_TIMEFRAMES timeframe,const int fast_ma_period=3, const int slow_ma_period=10, const ENUM_MA_METHOD ma_method=MODE_EMA, const ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK); int AddNewDEMA(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=14, const int ma_shift=0, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE); int AddNewDeMarker(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=14); int AddNewEnvelopes(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=14, const int ma_shift=0, const ENUM_MA_METHOD ma_method=MODE_SMA, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE, const double deviation=0.1); int AddNewForce(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=13, const ENUM_MA_METHOD ma_method=MODE_SMA, const ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK); int AddNewFractals(const string symbol,const ENUM_TIMEFRAMES timeframe); int AddNewFrAMA(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=14, const int ma_shift=0, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE); int AddNewGator(const string symbol,const ENUM_TIMEFRAMES timeframe,const int jaw_period=13, const int jaw_shift=8, const int teeth_period=8, const int teeth_shift=5, const int lips_period=5, const int lips_shift=3, const ENUM_MA_METHOD ma_method=MODE_SMMA, const ENUM_APPLIED_PRICE applied_price=PRICE_MEDIAN); int AddNewIchimoku(const string symbol,const ENUM_TIMEFRAMES timeframe,const int tenkan_sen=9, const int kijun_sen=26, const int senkou_span_b=52); int AddNewBWMFI(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK); int AddNewMomentum(const string symbol,const ENUM_TIMEFRAMES timeframe,const int mom_period=14, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE); int AddNewMFI(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=14, const ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK); int AddNewMA(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=10, const int ma_shift=0, const ENUM_MA_METHOD ma_method=MODE_SMA, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE); int AddNewOsMA(const string symbol,const ENUM_TIMEFRAMES timeframe,const int fast_ema_period=12, const int slow_ema_period=26, const int signal_period=9, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE); int AddNewMACD(const string symbol,const ENUM_TIMEFRAMES timeframe,const int fast_ema_period=12, const int slow_ema_period=26, const int signal_period=9, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE); int AddNewOBV(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK); int AddNewSAR(const string symbol,const ENUM_TIMEFRAMES timeframe,const double step=0.02, const double maximum=0.2); int AddNewRSI(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=14, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE); int AddNewRVI(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=10); int AddNewStdDev(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=20, const int ma_shift=0, const ENUM_MA_METHOD ma_method=MODE_SMA, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE); int AddNewStochastic(const string symbol,const ENUM_TIMEFRAMES timeframe,const int Kperiod=5, const int Dperiod=3, const int slowing=3, const ENUM_MA_METHOD ma_method=MODE_SMA, const ENUM_STO_PRICE price_field=STO_LOWHIGH); int AddNewTEMA(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=14, const int ma_shif=0, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE); int AddNewTriX(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=14, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE); int AddNewWPR(const string symbol,const ENUM_TIMEFRAMES timeframe,const int calc_period=14); int AddNewVIDyA(const string symbol,const ENUM_TIMEFRAMES timeframe,const int cmo_period=9, const int ema_period=12, const int ma_shift=0, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE); int AddNewVolumes(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK); int AddNewCustom(const string symbol,const ENUM_TIMEFRAMES timeframe,const string path, // путь к индикатору (например, "Examples\\MACD.ex5") const string name, // имя пользовательского индикатора (например, "Custom MACD") const uint buffers, // количество буферов const uint bars_to_calculate,// количество баров, необходимое для расчёта индикатора на текущем тике const MqlParam ¶m[]); // Массив параметров //--- Таймер void OnTimer(void) { //--- В цикле по всем индикаторам коллекции int total=this.m_list.Total(); for(int i=0;iWRONG_VALUE) { //--- сообщаем об этом в журнал и удаляем новый объект-индикатор ::PrintFormat("%s: The %s indicator with such parameters %s is already in the collection",source,ind_obj.Name(),ind_obj.Parameters()); delete ind_obj; //--- Получаем указатель на уже существующий объект-индикатор в списке и возвращаем его хэндл ind_obj=this.m_list.At(index); return(ind_obj!=NULL ? ind_obj.Handle() : INVALID_HANDLE); } //--- Если такого индикатора нет в списке, но его не удалось поместить в список if(!this.m_list.Add(ind_obj)) { //--- сообщаем об ошибке в журнал, удаляем объект-индикатор и возвращаем INVALID_HANDLE ::PrintFormat("%s: Error. Failed to add %s indicator to collection",source,ind_obj.Name()); delete ind_obj; return INVALID_HANDLE; } //--- Если индикатор помещён в список, но для него не удалось создать расчётную часть - возвращаем INVALID_HANDLE //--- (при ошибке создания расчётной части из списка объект-индикатор удаляется в методе CreateIndicator) if(!this.CreateIndicator(ind_obj)) return INVALID_HANDLE; //--- Всё успешно - сообщаем о добавлении нового индикатора в коллекцию и возвращаем его хэндл ::PrintFormat("%s: %s indicator (handle %ld) added to the collection",source,ind_obj.Title(),ind_obj.Handle()); return ind_obj.Handle(); } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Accelerator Oscillator | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewAC(const string symbol,const ENUM_TIMEFRAMES timeframe) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndAC *ind_obj=new CIndAC(symbol,timeframe); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create AC indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); ind_obj.SetBufferInitColorIndex(0,0); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Accumulation/Distribution | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewAD(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndAD *ind_obj=new CIndAD(symbol,timeframe,applied_volume); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create A/D indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+--------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Average Directional Movement Index | //+--------------------------------------------------------------------+ int CMSTFIndicators::AddNewADX(const string symbol,const ENUM_TIMEFRAMES timeframe,const int adx_period=14) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndADX *ind_obj=new CIndADX(symbol,timeframe,adx_period); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create ADX indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(MAIN_LINE,EMPTY_VALUE); ind_obj.SetBufferInitValue(PLUSDI_LINE,EMPTY_VALUE); ind_obj.SetBufferInitValue(MINUSDI_LINE,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор | //| Average Directional Movement Index by Welles Wilder | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewADXWilder(const string symbol,const ENUM_TIMEFRAMES timeframe,const int adx_period=14) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndADXW *ind_obj=new CIndADXW(symbol,timeframe,adx_period); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create ADX Wilder indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(MAIN_LINE,EMPTY_VALUE); ind_obj.SetBufferInitValue(PLUSDI_LINE,EMPTY_VALUE); ind_obj.SetBufferInitValue(MINUSDI_LINE,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Alligator | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewAlligator(const string symbol,const ENUM_TIMEFRAMES timeframe, const int jaw_period=13, const int jaw_shift=8, const int teeth_period=8, const int teeth_shift=5, const int lips_period=5, const int lips_shift=3, const ENUM_MA_METHOD ma_method=MODE_SMMA, const ENUM_APPLIED_PRICE applied_price=PRICE_MEDIAN) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndAlligator *ind_obj=new CIndAlligator(symbol,timeframe,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create Alligator indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(GATORJAW_LINE,EMPTY_VALUE); ind_obj.SetBufferInitValue(GATORTEETH_LINE,EMPTY_VALUE); ind_obj.SetBufferInitValue(GATORLIPS_LINE,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Adaptive Moving Average | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewAMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ama_period=9, const int fast_ma_period=2, const int slow_ma_period=30, const int ama_shift=0, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndAMA *ind_obj=new CIndAMA(symbol,timeframe,ama_period,fast_ma_period,slow_ma_period,ama_shift,applied_price); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create AMA indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Awesome Oscillator | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewAO(const string symbol,const ENUM_TIMEFRAMES timeframe) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndAO *ind_obj=new CIndAO(symbol,timeframe); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create AO indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); ind_obj.SetBufferInitColorIndex(0,0); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Average True Range | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewATR(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=14) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndATR *ind_obj=new CIndATR(symbol,timeframe,ma_period); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create ATR indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Bears Power | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewBearsPower(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=13) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndBears *ind_obj=new CIndBears(symbol,timeframe,ma_period); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create Bears indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Bulls Power | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewBullsPower(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=13) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndBulls *ind_obj=new CIndBulls(symbol,timeframe,ma_period); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create Bulls indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Bollinger Bands® | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewBands(const string symbol,const ENUM_TIMEFRAMES timeframe, const int bands_period=20, const int bands_shift=0, const double deviation=2.0, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndBands *ind_obj=new CIndBands(symbol,timeframe,bands_period,bands_shift,deviation,applied_price); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create Bands indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(BASE_LINE,EMPTY_VALUE); ind_obj.SetBufferInitValue(UPPER_BAND,EMPTY_VALUE); ind_obj.SetBufferInitValue(LOWER_BAND,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Commodity Channel Index | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewCCI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period=14, const ENUM_APPLIED_PRICE applied_price=PRICE_TYPICAL) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndCCI *ind_obj=new CIndCCI(symbol,timeframe,ma_period,applied_price); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create CCI indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_LEVELS,2); ::IndicatorSetDouble(INDICATOR_LEVELVALUE,0,-100.0); ::IndicatorSetDouble(INDICATOR_LEVELVALUE,1, 100.0); ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Chaikin Oscillator | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewChaikin(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ma_period=3, const int slow_ma_period=10, const ENUM_MA_METHOD ma_method=MODE_EMA, const ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndCHO *ind_obj=new CIndCHO(symbol,timeframe,fast_ma_period,slow_ma_period,ma_method,applied_volume); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create Chaikin indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+-------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Double Exponential Moving Average | //+-------------------------------------------------------------------+ int CMSTFIndicators::AddNewDEMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period=14, const int ma_shift=0, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndDEMA *ind_obj=new CIndDEMA(symbol,timeframe,ma_period,ma_shift,applied_price); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create DEMA indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор DeMarker | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewDeMarker(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=14) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndDeM *ind_obj=new CIndDeM(symbol,timeframe,ma_period); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create DeMarker indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_LEVELS,2); ::IndicatorSetDouble(INDICATOR_LEVELVALUE,0,0.3); ::IndicatorSetDouble(INDICATOR_LEVELVALUE,1,0.7); ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Envelopes | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewEnvelopes(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period=14, const int ma_shift=0, const ENUM_MA_METHOD ma_method=MODE_SMA, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE, const double deviation=0.1) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndEnvelopes *ind_obj=new CIndEnvelopes(symbol,timeframe,ma_period,ma_shift,ma_method,applied_price,deviation); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create Envelopes indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(UPPER_LINE,EMPTY_VALUE); ind_obj.SetBufferInitValue(LOWER_LINE,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Force Index | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewForce(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period=13, const ENUM_MA_METHOD ma_method=MODE_SMA, const ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndForce *ind_obj=new CIndForce(symbol,timeframe,ma_period,ma_method,applied_volume); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create Force indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Fractals | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewFractals(const string symbol,const ENUM_TIMEFRAMES timeframe) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndFractals *ind_obj=new CIndFractals(symbol,timeframe); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create Fractals indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(UPPER_LINE,EMPTY_VALUE); ind_obj.SetBufferInitValue(LOWER_LINE,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Fractal Adaptive Moving Average | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewFrAMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period=14, const int ma_shift=0, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndFrAMA *ind_obj=new CIndFrAMA(symbol,timeframe,ma_period,ma_shift,applied_price); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create FrAMA indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Gator | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewGator(const string symbol,const ENUM_TIMEFRAMES timeframe, const int jaw_period=13, const int jaw_shift=8, const int teeth_period=8, const int teeth_shift=5, const int lips_period=5, const int lips_shift=3, const ENUM_MA_METHOD ma_method=MODE_SMMA, const ENUM_APPLIED_PRICE applied_price=PRICE_MEDIAN) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndGator *ind_obj=new CIndGator(symbol,timeframe,jaw_period,jaw_shift,teeth_period,teeth_shift,lips_period,lips_shift,ma_method,applied_price); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create Gator indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Ichimoku Kinko Hyo | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewIchimoku(const string symbol,const ENUM_TIMEFRAMES timeframe, const int tenkan_sen=9, const int kijun_sen=26, const int senkou_span_b=52) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndIchimoku *ind_obj=new CIndIchimoku(symbol,timeframe,tenkan_sen,kijun_sen,senkou_span_b); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create Ichimoku indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Market Facilitation Index | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewBWMFI(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndBWMFI *ind_obj=new CIndBWMFI(symbol,timeframe,applied_volume); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create BW MFI indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); ind_obj.SetBufferInitColorIndex(0,0); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Momentum | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewMomentum(const string symbol,const ENUM_TIMEFRAMES timeframe, const int mom_period=14, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndMomentum *ind_obj=new CIndMomentum(symbol,timeframe,mom_period,applied_price); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create Momentum indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Money Flow Index | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewMFI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period=14, const ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndMFI *ind_obj=new CIndMFI(symbol,timeframe,ma_period,applied_volume); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create MFI indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_LEVELS,2); ::IndicatorSetDouble(INDICATOR_LEVELVALUE,0,20.0); ::IndicatorSetDouble(INDICATOR_LEVELVALUE,1,80.0); ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Moving Average | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period=10, const int ma_shift=0, const ENUM_MA_METHOD ma_method=MODE_SMA, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndMA *ind_obj=new CIndMA(symbol,timeframe,ma_period,ma_shift,ma_method,applied_price); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create MA indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Moving Average of Oscillator | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewOsMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ema_period=12, const int slow_ema_period=26, const int signal_period=9, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndOsMA *ind_obj=new CIndOsMA(symbol,timeframe,fast_ema_period,slow_ema_period,signal_period,applied_price); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create OsMA indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор | //| Moving Averages Convergence/Divergence | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewMACD(const string symbol,const ENUM_TIMEFRAMES timeframe, const int fast_ema_period=12, const int slow_ema_period=26, const int signal_period=9, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndMACD *ind_obj=new CIndMACD(symbol,timeframe,fast_ema_period,slow_ema_period,signal_period,applied_price); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create MACD indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(MAIN_LINE,EMPTY_VALUE); ind_obj.SetBufferInitValue(SIGNAL_LINE,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор On Balance Volume | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewOBV(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndOBV *ind_obj=new CIndOBV(symbol,timeframe,applied_volume); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create OBV indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+-------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Parabolic Stop and Reverse system | //+-------------------------------------------------------------------+ int CMSTFIndicators::AddNewSAR(const string symbol,const ENUM_TIMEFRAMES timeframe, const double step=0.02, const double maximum=0.2) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndSAR *ind_obj=new CIndSAR(symbol,timeframe,step,maximum); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create SAR indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Relative Strength Index | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewRSI(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period=14, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndRSI *ind_obj=new CIndRSI(symbol,timeframe,ma_period,applied_price); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create RSI indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_LEVELS,2); ::IndicatorSetDouble(INDICATOR_LEVELVALUE,0,30.0); ::IndicatorSetDouble(INDICATOR_LEVELVALUE,1,70.0); ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Relative Vigor Index | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewRVI(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ma_period=10) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndRVI *ind_obj=new CIndRVI(symbol,timeframe,ma_period); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create RVI indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(MAIN_LINE,EMPTY_VALUE); ind_obj.SetBufferInitValue(SIGNAL_LINE,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Standard Deviation | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewStdDev(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period=20, const int ma_shift=0, const ENUM_MA_METHOD ma_method=MODE_SMA, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndStdDev *ind_obj=new CIndStdDev(symbol,timeframe,ma_period,ma_shift,ma_method,applied_price); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create StdDev indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Stochastic Oscillator | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewStochastic(const string symbol,const ENUM_TIMEFRAMES timeframe, const int Kperiod=5, const int Dperiod=3, const int slowing=3, const ENUM_MA_METHOD ma_method=MODE_SMA, const ENUM_STO_PRICE price_field=STO_LOWHIGH) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndStoch *ind_obj=new CIndStoch(symbol,timeframe,Kperiod,Dperiod,slowing,ma_method,price_field); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create Stochastic indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_LEVELS,2); ::IndicatorSetDouble(INDICATOR_LEVELVALUE,0,20.0); ::IndicatorSetDouble(INDICATOR_LEVELVALUE,1,80.0); ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(MAIN_LINE,EMPTY_VALUE); ind_obj.SetBufferInitValue(SIGNAL_LINE,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+-------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Triple Exponential Moving Average | //+-------------------------------------------------------------------+ int CMSTFIndicators::AddNewTEMA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period=14, const int ma_shift=0, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndTEMA *ind_obj=new CIndTEMA(symbol,timeframe,ma_period,ma_shift,applied_price); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create TEMA indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор | //| Triple Exponential Moving Averages Oscillator | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewTriX(const string symbol,const ENUM_TIMEFRAMES timeframe, const int ma_period=14, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndTriX *ind_obj=new CIndTriX(symbol,timeframe,ma_period,applied_price); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create TriX indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Larry Williams' Percent Range | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewWPR(const string symbol,const ENUM_TIMEFRAMES timeframe,const int calc_period=14) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndWPR *ind_obj=new CIndWPR(symbol,timeframe,calc_period); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create WPR indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_LEVELS,2); ::IndicatorSetDouble(INDICATOR_LEVELVALUE,0,-80.0); ::IndicatorSetDouble(INDICATOR_LEVELVALUE,1,-20.0); ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Variable Index Dynamic Average | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewVIDyA(const string symbol,const ENUM_TIMEFRAMES timeframe, const int cmo_period=9, const int ema_period=12, const int ma_shift=0, const ENUM_APPLIED_PRICE applied_price=PRICE_CLOSE) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndVIDyA *ind_obj=new CIndVIDyA(symbol,timeframe,cmo_period,ema_period,ma_shift,applied_price); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create VIDyA indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию индикатор Volumes | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewVolumes(const string symbol,const ENUM_TIMEFRAMES timeframe,const ENUM_APPLIED_VOLUME applied_volume=VOLUME_TICK) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndVolumes *ind_obj=new CIndVolumes(symbol,timeframe,applied_volume); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create Volumes indicator object",__FUNCTION__); return INVALID_HANDLE; } //--- Получаем результат добавления созданного объекта-индикатора в список коллекцию (хэндл индикатора) int handle=this.AddNewIndicator(ind_obj,__FUNCTION__); //--- Если индикатор успешно создан и добавлен в коллекцию, установим параметры его отображения if(handle!=INVALID_HANDLE && ::CheckPointer(ind_obj)!=POINTER_INVALID) { ::IndicatorSetInteger(INDICATOR_DIGITS,ind_obj.Digits()); ind_obj.SetBufferInitValue(0,EMPTY_VALUE); ind_obj.SetBufferInitColorIndex(0,0); } //--- Возвращаем хэндл созданного индикатора, либо INVALID_HANDLE return handle; } //+------------------------------------------------------------------+ //| Добавляет в коллекцию пользовательский индикатор | //+------------------------------------------------------------------+ int CMSTFIndicators::AddNewCustom(const string symbol,const ENUM_TIMEFRAMES timeframe,const string path,const string name,const uint buffers,const uint bars_to_calculate,const MqlParam ¶m[]) { //--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE CIndCustom *ind_obj=new CIndCustom(symbol,timeframe,path,name,buffers,bars_to_calculate,param); if(ind_obj==NULL) { ::PrintFormat("%s: Error. Failed to create %s custom indicator object",__FUNCTION__,name); return INVALID_HANDLE; } //--- Возвращаем результат добавления созданного объекта-индикатора в список коллекцию return this.AddNewIndicator(ind_obj,__FUNCTION__); } //+------------------------------------------------------------------+