Article-13578-MQL5-Multi-Sy.../IndMSTF.mqh

6004 lines
No EOL
647 KiB
MQL5

//+------------------------------------------------------------------+
//| 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 <Object.mqh>
//--- 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(idx<clrs.Size() ? clrs[idx] : clrNONE); }
};
//+------------------------------------------------------------------+
//| Возвращает описание состояния линии индикатора |
//+------------------------------------------------------------------+
string BufferLineStateDescription(const ENUM_LINE_STATE state)
{
switch(state)
{
case LINE_STATE_NONE : return "None";
case LINE_STATE_UP : return "Up";
case LINE_STATE_STOP_UP : return "Stop Up";
case LINE_STATE_TURN_UP : return "Turn Up";
case LINE_STATE_DOWN : return "Down";
case LINE_STATE_STOP_DOWN : return "Stop Down";
case LINE_STATE_TURN_DOWN : return "Turn Down";
case LINE_STATE_ABOVE : return "Above level";
case LINE_STATE_BELOW : return "Below level";
case LINE_STATE_CROSS_UP : return "Crossing Up";
case LINE_STATE_CROSS_DOWN : return "Crossing Down";
case LINE_STATE_TOUCH_BELOW: return "Touch from Below";
case LINE_STATE_TOUCH_ABOVE: return "Touch from Above";
case LINE_STATE_EQUALS : return "Equals";
default : return "Unknown";
}
}
//+------------------------------------------------------------------+
//| Возвращает описание ошибки при расчёте индикатора |
//+------------------------------------------------------------------+
string TypeErrorcDescription(ENUM_ERR_TYPE error_type)
{
switch(error_type)
{
case ERR_TYPE_NO_SYNC : return "Data is not synchronized";
case ERR_TYPE_NO_DATA : return "Data not loaded";
case ERR_TYPE_NO_CALC : return "Calculation not completed";
default : return "No error";
}
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Базовый класс мультисимвольного мультипериодного индикатора |
//+------------------------------------------------------------------+
class CIndMSTF : public CObject
{
private:
ENUM_PROGRAM_TYPE m_program; // Тип программы
ENUM_INDICATOR m_type; // Тип индикатора
ENUM_TIMEFRAMES m_timeframe; // Период графика
string m_symbol; // Символ графика
int m_handle; // Хэндл индикатора
int m_id; // Идентификатор
bool m_success; // Флаг успешного расчёта
ENUM_ERR_TYPE m_type_err; // Тип ошибки при расчёте
string m_description; // Пользовательское описание индикатора
string m_name; // Наименование индикатора
string m_parameters; // Описание параметров индикатора
double m_array_data[]; // Временный массив для копирования данных
datetime m_array_time[]; // Временный массив для копирования времени
protected:
ENUM_IND_CATEGORY m_category; // Категория индикатора
MqlParam m_param[]; // Массив параметров индикатора
string m_title; // Заголовок (наименование индикатора + описание параметров)
SBuffer m_buffers[]; // Буферы индикатора
int m_digits; // Digits значений индикатора
int m_limit; // Количество баров, необходимое для просчёта индикатора на текущем тике
int m_rates_total; // Количество доступных баров для просчёта индикатора
int m_prev_calculated; // Количество просчитанных баров на прошлом вызове индикатора
uint m_bars_to_calculate; // Количество баров, необходимое для расчёта индикатора на текущем тике
//--- (1) Устанавливает наименование индикатора, (2) описание параметров
void SetName(const string name) { this.m_name=name; }
void SetParameters(const string str) { this.m_parameters=str; }
//--- Изменяет размер (1) указанного, (2) всех буферов индикатора
bool BufferResize(const uint buffer_num,const int new_buff_size);
bool BuffersResize(const int new_buff_size);
//--- Инициализирует (1) укакзанный, (2) все буферы индикатора
bool BufferInitialize(const uint buffer_num,const int new_buff_size);
bool BuffersInitialize(const int new_buff_size);
//--- Возвращает флаг равенства структуры одного параметра двух объектов
bool IsEqualParameters(const MqlParam &this_param,const MqlParam &compared_param) const
{
if(this_param.type==compared_param.type &&
this_param.integer_value==compared_param.integer_value &&
this_param.string_value==compared_param.string_value &&
::NormalizeDouble(this_param.double_value-compared_param.double_value,8)==0
) return true;
return false;
}
//--- Возвращает результат сравнения одного параметра двух объектов
int CompareParams(const MqlParam &this_param,const MqlParam &compared_param)
{
if(this.IsEqualParameters(this_param,compared_param))
return 0;
else if(this_param.type>compared_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.type<compared_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
return -1;
}
//--- Копирует данные указанного массива указанного буфера
bool CopyArray(const uint buff_num,const uint array_num,const int to_copy,double &array[]);
//--- Копирует данные всех массивов указанного буфера
bool CopyArrays(const uint buff_num,const int to_copy);
public:
//--- Создаёт расчётную часть индикатора, возвращает хэндл
int CreateIndicator(void);
//--- (1) Рассчитывает индикатор, заполняет переданный (2) рисуемый массив-буфер, (3) массив-буфер индексов цвета (с учётом символа-периода графика) данными из буфера расчётной части индикатора данного класса
bool Calculate(void);
bool DataToBuffer(const string symbol_to,const ENUM_TIMEFRAMES timeframe_to,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 uint buffer_num,const uint array_num,const int limit,double &plot_buffer[],double &color_buffer[]);
//--- (1) Устанавливает (2) возвращает инициализирующее значение для указанного буфера
void SetBufferInitValue(const uint buffer_num,const double value);
double BufferInitValue(const uint buffer_num) const;
//--- (1) Устанавливает (2) возвращает инициализирующее значение индекса цвета для указанного буфера
void SetBufferInitColorIndex(const uint buffer_num,const uchar index);
uchar BufferInitColorIndex(const uint buffer_num) const;
//--- (1) Устанавливает, (2) возвращает значение цвета по индексу для указанного буфера
void SetBufferColorToIndex(const uint buffer_num,const uchar color_idx,const color clr);
color BufferColorByIndex(const uint buffer_num,const uchar color_idx);
//--- Возвращает флаг цветного буфера
bool IsColoredBuffer(const uint buffer_num) const;
//--- (1) Устанавливает (2) возвращает значение сдвига для указанного буфера
void SetBufferShift(const uint buffer_num,const int value);
double BufferShift(const uint buffer_num) const;
//--- (1) Устанавливает, (2) возвращает стиль рисования указанного буфера, (3) номер соответствующего буфера исходного индикатора
void SetBufferDrawType(const uint buffer_num,const ENUM_DRAW_TYPE type,const uint buff_source);
ENUM_DRAW_TYPE BufferDrawType(const uint buffer_num);
uint BufferFrom(const uint buffer_num);
//--- Возвращает данные указанного буфера и массива (1) как есть, (2) относительно указанного символа/таймфрейма,
//--- данные указанного буфера цвета (3) как есть, (4) относительно указанного символа/таймфрейма,
//--- (5) количество данных в указанном буфере, (7) количество цветов, установленных буферу, (7) состояние линии индикатора как есть в буфере расчётной части,
//--- (8) состояние линии индикатора с учётом символа/периода графика, описание состояния линии (9) как есть в буфере (10) с учётом символа/периода графика
double GetData(const uint buffer_num,const uint array_num,const int index) const;
double GetDataTo(const string symbol_to,const ENUM_TIMEFRAMES timeframe_to,const uint buffer_num,const uint array_num,const int index) const;
double GetColorData(const uint buffer_num,const int index) const;
double GetColorDataTo(const string symbol_to,const ENUM_TIMEFRAMES timeframe_to,const uint buffer_num,const int index) const;
uint DataTotal(const uint buffer_num,const uint array_num) const;
uint ColorsTotal(const uint buffer_num) const;
ENUM_LINE_STATE BufferLineState(const uint buffer_num,const uint array_num,const int index) const;
ENUM_LINE_STATE BufferLineState(const string symbol_from,const ENUM_TIMEFRAMES timeframes_from,const uint buffer_num,const uint array_num,const int index) const;
ENUM_LINE_STATE BufferLineStateRelative(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_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);
//--- Возвращает (1) флаг успешности, (2) тип ошибки расчёта
bool IsSuccess(void) const { return this.m_success; }
ENUM_ERR_TYPE TypeError(void) const { return this.m_type_err; }
//--- Устанавливает (1) идентификатор, (2) Digits, (3) пользовательское описание, (4) описание указанного буфера
void SetID(const int id) { this.m_id=id; }
void SetDigits(const uint digits) { this.m_digits=(int)digits; }
void SetDescription(const string descr) { this.m_description=descr; }
void SetBufferDescription(const uint buffer_num,const string descr);
//--- Устанавливает индексацию массивов буферов расчётной части не как в таймсерии
void SetAsSeriesOff(void);
//--- Возвращает флаг серийности указанного буфера, (2) синхронизированности исторических данных по символу/периоду
bool IsSeries(const uint buffer_num,const uint array_num) const;
bool IsSynchronized(void) const
{
return (bool)::SeriesInfoInteger(this.m_symbol,this.m_timeframe,SERIES_SYNCHRONIZED);
}
//--- Возвращает (1) таймфрейм, (2) символ, (3) наименование, (4) список параметров, (5) хэндл, (6) Digits
//--- количество (7) буферов, (8) баров, (9) идентификатор, (10) описание, (11) заголовок, (12) категорию,
//--- (13) количество параметрпов, (14) тип программы, описание (15) категории, (16) буфера индикатора
ENUM_TIMEFRAMES Timeframe(void) const { return this.m_timeframe; }
string Symbol(void) const { return this.m_symbol; }
string Name(void) const { return this.m_name; }
string Parameters(void) const { return this.m_parameters; }
int Handle(void) const { return this.m_handle; }
int Digits(void) const { return this.m_digits; }
uint BuffersTotal(void) const { return this.m_buffers.Size(); }
uint RatesTotal(void) const { return this.m_rates_total; }
int ID(void) const { return this.m_id; }
string Description(void) const { return this.m_description; }
string Title(void) const { return this.m_title; }
ENUM_IND_CATEGORY Category(void) const { return this.m_category; }
uint ParamsTotal(void) const { return this.m_param.Size(); }
ENUM_PROGRAM_TYPE Program(void) const { return this.m_program; }
string CategoryDescription(void);
string BufferDescription(const uint buffer_num);
//--- Возвращает (1) структуру параметров по индексу из массива, (2) флаг программы-индикатора, (3) описание таймфрейма
MqlParam GetMqlParam(const int index) const { return this.m_param[index]; }
bool IsIndicator() const { return(this.Program()==PROGRAM_INDICATOR); }
string TimeframeDescription(void) const
{
return ::StringSubstr(::EnumToString(this.m_timeframe),7);
}
//--- Возвращает количество рассчитанных данных
int Calculated(void) const { return ::BarsCalculated(this.m_handle); }
//--- Устанавливает количество баров, необходимое для расчёта индикатора на текущем тике
void SetBarsToCalculate(const int bars)
{
this.m_bars_to_calculate=bars;
if(this.m_array_data.Size()!=this.m_bars_to_calculate)
{
::ArrayResize(this.m_array_data,this.m_bars_to_calculate);
::ArrayResize(this.m_array_time,this.m_bars_to_calculate);
}
}
//--- Виртуальный метод, возвращающий тип объекта (индикатора)
virtual int Type(void) const { return this.m_type; }
//--- Виртуальный метод сравнения двух объектов
virtual int Compare(const CObject *node,const int mode=0) const
{
const CIndMSTF *compared=node;
switch(mode)
{
case COMPARE_MODE_ID : return(this.ID()>compared.ID() ? 1 : this.ID()<compared.ID() ? -1 : 0);
case COMPARE_MODE_HANDLE : return(this.Handle()>compared.Handle() ? 1 : this.Handle()<compared.Handle() ? -1 : 0);
case COMPARE_MODE_CATEGORY : return(this.Category()>compared.Category() ? 1 : this.Category()<compared.Category() ? -1 : 0);
case COMPARE_MODE_SYMBOL : return(this.Symbol()>compared.Symbol() ? 1 : this.Symbol()<compared.Symbol() ? -1 : 0);
case COMPARE_MODE_TIMEFRAME : return(this.Timeframe()>compared.Timeframe() ? 1 : this.Timeframe()<compared.Timeframe() ? -1 : 0);
case COMPARE_MODE_DESCRIPTION : return(this.Description()>compared.Description() ? 1 : this.Description()<compared.Description() ? -1 : 0);
//---Равенство всех параметров объектов
default : return(this.IsEqualIndicators(compared) ? 0 : -1);
}
}
//--- Возвращает флаг равенства параметров двух объектов-индикаторов
bool IsEqualIndicators(const CIndMSTF *compared) const
{
if(this.Type()!=compared.Type() || this.ParamsTotal()!=compared.ParamsTotal())
return false;
bool res=true;
int total=(int)this.ParamsTotal();
for(int i=0;i<total;i++)
res &=this.IsEqualParameters(this.m_param[i],compared.GetMqlParam(i));
res &=(this.Timeframe()==compared.Timeframe());
res &=(this.Symbol()==compared.Symbol());
return res;
}
//--- Таймер
void OnTimer(void);
//--- Конструктор/деструктор
CIndMSTF(){}
CIndMSTF(const ENUM_INDICATOR type,const uint buffers,const string symbol,const ENUM_TIMEFRAMES timeframe);
~CIndMSTF();
};
//+------------------------------------------------------------------+
//| Конструктор |
//+------------------------------------------------------------------+
CIndMSTF::CIndMSTF(const ENUM_INDICATOR type,const uint buffers,const string symbol,const ENUM_TIMEFRAMES timeframe)
{
//--- Запускаем таймер
::ResetLastError();
if(!::EventSetTimer(1))
::PrintFormat("%s: EventSetTimer failed. Error %lu",__FUNCTION__,::GetLastError());
//--- Устанавливаем свойствам переданные в конструктор значения, или значения по умолчанию
this.m_program=(ENUM_PROGRAM_TYPE)::MQLInfoInteger(MQL_PROGRAM_TYPE);
this.m_type=type;
this.m_symbol=(symbol==NULL || symbol=="" ? ::Symbol() : symbol);
this.m_timeframe=(timeframe==PERIOD_CURRENT ? ::Period() : timeframe);
this.m_handle=INVALID_HANDLE;
this.m_digits=::Digits();
this.m_success=true;
this.m_type_err=ERR_TYPE_NO_ERROR;
//--- Устанавливаем массиву структуре буферов размер, равный количеству буферов индикатора
::ResetLastError();
if(::ArrayResize(this.m_buffers,buffers)!=buffers)
::PrintFormat("%s: Buffers ArrayResize failed. Error %lu"__FUNCTION__,::GetLastError());
//--- Устанавливаем "пустое" значение для каждого буфера по умолчанию (потом можно изменить)
for(int i=0;i<(int)this.m_buffers.Size();i++)
this.SetBufferInitValue(i,EMPTY_VALUE);
//--- Устанавливаем начальные значения переменным, участвующим в экономном расчёте индикатора
this.m_prev_calculated=0;
this.m_limit=0;
this.m_rates_total=::Bars(this.m_symbol,this.m_timeframe);
this.SetBarsToCalculate(2);
//--- Если индикатор рассчитывается не на текущем графике - делаем запрос данных с нужного графика
//--- (первое обращение к данным запускает подкачку этих данных)
datetime array[];
if(symbol!=::Symbol() || timeframe!=::Period())
::CopyTime(this.m_symbol,this.m_timeframe,0,this.m_rates_total,array);
}
//+------------------------------------------------------------------+
//| Деструктор |
//+------------------------------------------------------------------+
CIndMSTF::~CIndMSTF()
{
//--- Удаляем таймер
::EventKillTimer();
//--- Освобождаем хэндл индикатора
::ResetLastError();
if(this.m_handle!=INVALID_HANDLE && !::IndicatorRelease(this.m_handle))
::PrintFormat("%s: %s, handle %ld IndicatorRelease failed. Error %ld",__FUNCTION__,this.Title(),m_handle,::GetLastError());
//--- Освобождаем память массивов буферов
for(int i=0;i<(int)this.BuffersTotal();i++)
{
::ArrayFree(this.m_buffers[i].array0);
::ArrayFree(this.m_buffers[i].array1);
::ArrayFree(this.m_buffers[i].array2);
::ArrayFree(this.m_buffers[i].array3);
::ArrayFree(this.m_buffers[i].color_indexes);
}
//--- Освобождаем память временных массивов
::ArrayFree(this.m_array_data);
::ArrayFree(this.m_array_time);
}
//+------------------------------------------------------------------+
//| Таймер |
//+------------------------------------------------------------------+
void CIndMSTF::OnTimer(void)
{
//--- Если символ и таймфрейм индикатора такие же, как у текущего графика - уходим
if(this.Symbol()==::Symbol() && this.Timeframe()==::Period())
return;
//--- Объявляем переменные счётчиков таймера
static int count1=0;
static int count2=0;
//--- Если счётчик таймера 1 достиг заданного значения,
if(count1>=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;i<total;i++)
res &=this.m_buffers[i].BuffResize(new_buff_size);
//--- Возвращаем результат изменения размеров всех массивов буферов индикатора
return res;
}
//+------------------------------------------------------------------+
//| Инициализирует указанный буфер индикатора |
//+------------------------------------------------------------------+
bool CIndMSTF::BufferInitialize(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;
}
//--- Изменяем размер массива буфера
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;i<total;i++)
{
res &=this.m_buffers[i].BuffResize(new_buff_size);
if(res)
this.m_buffers[i].InitBuffer();
}
//--- Возвращаем общий результат
return res;
}
//+------------------------------------------------------------------+
//| Устанавливает инициализирующее значение для указанного буфера |
//+------------------------------------------------------------------+
void CIndMSTF::SetBufferInitValue(const uint buffer_num,const double 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].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;i<total;i++)
this.m_buffers[buff_num].array0[this.DataTotal(buff_num,0)-(total-i)]=this.m_array_data[i];
}
return res;
//--- Два буфера
case DRAW_HISTOGRAM2 :
case DRAW_ZIGZAG :
case DRAW_FILLING :
res=this.CopyArray(buff_num,0,to_copy,this.m_array_data);
if(res)
{
for(int i=0;i<total;i++)
this.m_buffers[buff_num].array0[this.DataTotal(buff_num,0)-(total-i)]=this.m_array_data[i];
}
res &=this.CopyArray(buff_num,1,to_copy,this.m_array_data);
if(res)
{
for(int i=0;i<total;i++)
this.m_buffers[buff_num].array1[this.DataTotal(buff_num,1)-(total-i)]=this.m_array_data[i];
}
return res;
//--- Четыре буфера
case DRAW_BARS :
case DRAW_CANDLES :
res=this.CopyArray(buff_num,0,to_copy,this.m_array_data);
if(res)
{
for(int i=0;i<total;i++)
this.m_buffers[buff_num].array0[this.DataTotal(buff_num,0)-(total-i)]=this.m_array_data[i];
}
res &=this.CopyArray(buff_num,1,to_copy,this.m_array_data);
if(res)
{
for(int i=0;i<total;i++)
this.m_buffers[buff_num].array1[this.DataTotal(buff_num,1)-(total-i)]=this.m_array_data[i];
}
res &=this.CopyArray(buff_num,2,to_copy,this.m_array_data);
if(res)
{
for(int i=0;i<total;i++)
this.m_buffers[buff_num].array2[this.DataTotal(buff_num,2)-(total-i)]=this.m_array_data[i];
}
res &=this.CopyArray(buff_num,3,to_copy,this.m_array_data);
if(res)
{
for(int i=0;i<total;i++)
this.m_buffers[buff_num].array3[this.DataTotal(buff_num,3)-(total-i)]=this.m_array_data[i];
}
return res;
//--- Один буфер + буфер цвета
case DRAW_COLOR_LINE :
case DRAW_COLOR_HISTOGRAM :
case DRAW_COLOR_ARROW :
case DRAW_COLOR_SECTION :
res=this.CopyArray(buff_num,0,to_copy,this.m_array_data);
if(res)
{
for(int i=0;i<total;i++)
this.m_buffers[buff_num].array0[this.DataTotal(buff_num,0)-(total-i)]=this.m_array_data[i];
}
res &=this.CopyArray(buff_num,4,to_copy,this.m_array_data);
if(res)
{
for(int i=0;i<total;i++)
this.m_buffers[buff_num].color_indexes[this.DataTotal(buff_num,4)-(total-i)]=this.m_array_data[i];
}
return res;
//--- Два буфера + буфер цвета
case DRAW_COLOR_HISTOGRAM2 :
case DRAW_COLOR_ZIGZAG :
res=this.CopyArray(buff_num,0,to_copy,this.m_array_data);
if(res)
{
for(int i=0;i<total;i++)
this.m_buffers[buff_num].array0[this.DataTotal(buff_num,0)-(total-i)]=this.m_array_data[i];
}
res &=this.CopyArray(buff_num,1,to_copy,this.m_array_data);
if(res)
{
for(int i=0;i<total;i++)
this.m_buffers[buff_num].array1[this.DataTotal(buff_num,1)-(total-i)]=this.m_array_data[i];
}
res &=this.CopyArray(buff_num,4,to_copy,this.m_array_data);
if(res)
{
for(int i=0;i<total;i++)
this.m_buffers[buff_num].color_indexes[this.DataTotal(buff_num,4)-(total-i)]=this.m_array_data[i];
}
return res;
//--- Четыре буфера + буфер цвета
case DRAW_COLOR_BARS :
case DRAW_COLOR_CANDLES :
res=this.CopyArray(buff_num,0,to_copy,this.m_array_data);
if(res)
{
for(int i=0;i<total;i++)
this.m_buffers[buff_num].array0[this.DataTotal(buff_num,0)-(total-i)]=this.m_array_data[i];
}
res &=this.CopyArray(buff_num,1,to_copy,this.m_array_data);
if(res)
{
for(int i=0;i<total;i++)
this.m_buffers[buff_num].array1[this.DataTotal(buff_num,1)-(total-i)]=this.m_array_data[i];
}
res &=this.CopyArray(buff_num,2,to_copy,this.m_array_data);
if(res)
{
for(int i=0;i<total;i++)
this.m_buffers[buff_num].array2[this.DataTotal(buff_num,2)-(total-i)]=this.m_array_data[i];
}
res &=this.CopyArray(buff_num,3,to_copy,this.m_array_data);
if(res)
{
for(int i=0;i<total;i++)
this.m_buffers[buff_num].array3[this.DataTotal(buff_num,3)-(total-i)]=this.m_array_data[i];
}
res &=this.CopyArray(buff_num,4,to_copy,this.m_array_data);
if(res)
{
for(int i=0;i<total;i++)
this.m_buffers[buff_num].color_indexes[this.DataTotal(buff_num,4)-(total-i)]=this.m_array_data[i];
}
return res;
//---DRAW_NONE
default:
break;
}
}
else
{
switch(this.BufferDrawType(buff_num))
{
//--- Один буфер
case DRAW_LINE :
case DRAW_HISTOGRAM :
case DRAW_ARROW :
case DRAW_SECTION :
return this.CopyArray(buff_num,0,to_copy,this.m_array_data);
//--- Два буфера
case DRAW_HISTOGRAM2 :
case DRAW_ZIGZAG :
case DRAW_FILLING :
res =this.CopyArray(buff_num,0,to_copy,this.m_array_data);
res &=this.CopyArray(buff_num,1,to_copy,this.m_array_data);
return res;
//--- Четыре буфера
case DRAW_BARS :
case DRAW_CANDLES :
res =this.CopyArray(buff_num,0,to_copy,this.m_array_data);
res &=this.CopyArray(buff_num,1,to_copy,this.m_array_data);
res &=this.CopyArray(buff_num,2,to_copy,this.m_array_data);
res &=this.CopyArray(buff_num,3,to_copy,this.m_array_data);
return res;
//--- Один буфер + буфер цвета
case DRAW_COLOR_LINE :
case DRAW_COLOR_HISTOGRAM :
case DRAW_COLOR_ARROW :
case DRAW_COLOR_SECTION :
res =this.CopyArray(buff_num,0,to_copy,this.m_array_data);
res &=this.CopyArray(buff_num,4,to_copy,this.m_array_data);
return res;
//--- Два буфера + буфер цвета
case DRAW_COLOR_HISTOGRAM2 :
case DRAW_COLOR_ZIGZAG :
res =this.CopyArray(buff_num,0,to_copy,this.m_array_data);
res &=this.CopyArray(buff_num,1,to_copy,this.m_array_data);
res &=this.CopyArray(buff_num,4,to_copy,this.m_array_data);
return res;
//--- Четыре буфера + буфер цвета
case DRAW_COLOR_BARS :
case DRAW_COLOR_CANDLES :
res =this.CopyArray(buff_num,0,to_copy,this.m_array_data);
res &=this.CopyArray(buff_num,1,to_copy,this.m_array_data);
res &=this.CopyArray(buff_num,2,to_copy,this.m_array_data);
res &=this.CopyArray(buff_num,3,to_copy,this.m_array_data);
res &=this.CopyArray(buff_num,4,to_copy,this.m_array_data);
return res;
//---DRAW_NONE
default:
break;
}
}
return false;
}
//+------------------------------------------------------------------+
//| Заполняет буферы объекта данными из буфера расчётной части |
//+------------------------------------------------------------------+
bool CIndMSTF::Calculate(void)
{
//--- Устанавливаем флагу успешности значение true, а типу ошибки - её отсутствие
this.m_success=true;
this.m_type_err=ERR_TYPE_NO_ERROR;
//--- Если данные ещё не синхронизированы с торговым сервером,
if(!this.IsSynchronized())
{
//--- Выводим в журнал сообщение о несинхронизированности,
::PrintFormat("%s::%s: Waiting for data to sync...",__FUNCTION__,this.Title());
//--- устанавливаем тип ошибки, к флагу ошибки добавляем false и возвращаем false
this.m_type_err=ERR_TYPE_NO_SYNC;
this.m_success=false;
return false;
}
//--- Если метод Calculated вернул -1, это означает начало закачки данных
if(this.Calculated()==WRONG_VALUE)
{
//--- Выводим в журнал сообщение о начале закачки данных,
::PrintFormat("%s::%s: Start downloading data by %s/%s. Waiting for the next tick...",__FUNCTION__,this.Title(),this.m_symbol,this.TimeframeDescription());
//--- устанавливаем тип ошибки, к флагу ошибки добавляем false и возвращаем false
this.m_type_err=ERR_TYPE_NO_DATA;
this.m_success=false;
return false;
}
//--- Если метод Calculated вернул 0, это означает, что индикатор ещё не рассчитан
if(this.Calculated()==0)
{
//--- Выводим в журнал сообщение об ожидании расчёта индикатора,
::PrintFormat("%s::%s: Waiting for a new tick and when the indicator will be calculated...",__FUNCTION__,this.Title());
//--- устанавливаем тип ошибки, к флагу ошибки добавляем false и возвращаем false
this.m_type_err=ERR_TYPE_NO_CALC;
this.m_success=false;
return false;
}
//--- Получаем количество баров данных по символу/периоду индикатора
int bars=::Bars(this.m_symbol,this.m_timeframe);
//--- Если функция Bars вернула нулевое значение, что часто бывает на выходных, рассчитаем доступное количество баров
if(bars==0)
{
//--- Получим дату самого первого доступного бара в истории по символу/периоду
datetime firstdate=(datetime)::SeriesInfoInteger(this.m_symbol,this.m_timeframe,SERIES_FIRSTDATE);
//--- Получим дату последнего (текущего) бара в истории по символу/периоду
datetime lastdate=(datetime)::SeriesInfoInteger(this.m_symbol,this.m_timeframe,SERIES_LASTBAR_DATE);
//--- Рассчитаем количество баров между первой и последней датами истории
int sec=::PeriodSeconds(this.m_timeframe);
ulong date_bars=(((ulong)lastdate-(ulong)firstdate)/(sec>0 ? 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;i<total;i++)
{
//--- изменяем размер массива буфера индикатора и инициализируем его установленным для этого буфера "пустым" значением
this.BufferInitialize(i,this.m_rates_total);
//--- Определяем количество копируемых данных
int to_copy=(this.m_prev_calculated>this.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;i<total;i++)
{
//--- Если это открытие нового бара и не удалось изменить размер буфера индикатора,
if(this.m_limit==1 && !this.BufferResize(i,this.m_rates_total))
{
//--- добавим к переменной m_success значение false и вернём false
//--- При этом сообщение об ошибке будет выведено в журнал из метода BufferResize
this.m_success=false;
return false;
}
//--- Если не удалось скопировать бары в количестве m_bars_to_calculate из буфера расчётной части индикатора,
::ResetLastError();
if(!this.CopyArrays(i,this.m_bars_to_calculate))
{
//--- сообщим об этом в журнал, добавим к переменной m_success значение false и вернём false
::PrintFormat("%s::%s: CopyBuffer(%lu) failed. Error %lu",__FUNCTION__,this.Title(),i,::GetLastError());
this.m_success &=false;
}
}
//--- Если после цикла есть ошибки - возвращаем false
if(!this.m_success)
{
this.m_type_err=ERR_TYPE_NO_DATA;
return false;
}
//--- Успешно
this.m_type_err=ERR_TYPE_NO_ERROR;
this.m_success=true;
return true;
}
//--- Неопределённый вариант limit - возвращаем false
return false;
}
//+------------------------------------------------------------------+
//| Заполняет переданный рисуемый массив данными из буфера класса |
//+------------------------------------------------------------------+
bool CIndMSTF::DataToBuffer(const string symbol_to,const ENUM_TIMEFRAMES timeframe_to,const uint buffer_num,const uint array_num,const int limit,double &buffer[])
{
//--- Устанавливаем флаг успешности
this.m_success=true;
//--- Получаем направление индексации переданного в метод массива буфера и,
//--- если индексация не как у таймсерии, - устанавливаем индексацию как у таймсерии
bool as_series=::ArrayGetAsSeries(buffer);
if(!as_series)
::ArraySetAsSeries(buffer,true);
//--- Устанавливаем наименование символа и значение таймфрейма, переданные в метод
string symbol=(symbol_to=="" || symbol_to==NULL ? ::Symbol() : symbol_to);
ENUM_TIMEFRAMES timeframe=(timeframe_to==PERIOD_CURRENT ? ::Period() : timeframe_to);
//--- Если это первый запуск, или изменения в истории - инициальзируем массив буфера, переданный в метод
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(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<count;i++)
{
//--- Если таймфрейм графика совпадает с таймфреймом объекта класса - заполняем буфер напрямую из массива объекта класса
if(timeframe==::Period() && this.m_timeframe==::Period())
buffer[i]=this.GetData(buffer_num,array_num,i);
//--- Иначе, если таймфрейм графика не равен таймфрейму объекта класса
else
{
//--- Если таймфрейм графика младше таймфрейма объекта класса,
if(timeframe<this.m_timeframe)
{
//--- Если это исторические данные (бар с индексом большим, чем m_bars_to_calculate-1)
if(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;i<count;i++)
{
//--- Если таймфрейм графика совпадает с таймфреймом объекта класса - заполняем буфер напрямую из массива объекта класса
if(timeframe==::Period() && this.m_timeframe==::Period())
{
plot_buffer[i]=this.GetData(buffer_num,array_num,i);
color_buffer[i]=this.GetColorData(buffer_num,i);
}
//--- Иначе, если таймфрейм графика не равен таймфрейму объекта класса
else
{
//--- Узнаём какому времени данного класса принадлежит бар текущего таймфрейма графика, соответствующий индексу цикла
::ResetLastError();
if(::CopyTime(symbol,timeframe,i,2,array)!=2)
{
//--- Если данных нет в терминале - идём дальше
if(::GetLastError()==4401)
continue;
//--- Ошибка получения существующих данных - возвращаем false
this.m_success &=false;
return false;
}
//--- По времени бара текущего таймфрейма графика находим соответствующий индекс бара периода графика объекта класса
::ResetLastError();
int bar=::iBarShift(this.m_symbol,this.m_timeframe,array[0]);
if(bar==WRONG_VALUE)
{
this.m_success &=false;
continue;
}
//--- Если это исторические данные (не первый и не нулевой бар) -
//--- записываем в буфер индикатора по индексу цикла значение, полученное из буфера расчётной части
if(i>1)
{
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<this.m_timeframe)
{
//--- в цикле от бара с меньшим временем до текущего бара графика заполняем буфер данными из двух последних ячеек массива буфера индикатора
for(int j=bar1;j>=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<value1)
if(::NormalizeDouble(value2-value1,this.m_digits)<0 && ::NormalizeDouble(value0-value1,this.m_digits)<0)
return LINE_STATE_TURN_DOWN;
//--- Направление линии вниз (value2>=value1 && value0<value1)
else if(::NormalizeDouble(value2-value1,this.m_digits)>=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<value1)
if(::NormalizeDouble(value2-value1,this.m_digits)<0 && ::NormalizeDouble(value0-value1,this.m_digits)<0)
return LINE_STATE_TURN_DOWN;
//--- Направление линии вниз (value2>=value1 && value0<value1)
else if(::NormalizeDouble(value2-value1,this.m_digits)>=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);
//--- Линия находится под уровнем (value1<level && value0<level0)
if(::NormalizeDouble(value1-level,this.m_digits)<0 && ::NormalizeDouble(value0-level0,this.m_digits)<0)
return LINE_STATE_BELOW;
//--- Линия находится над уровнем (value1>level && 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<level0)
if(::NormalizeDouble(value1-level,this.m_digits)>=0 && ::NormalizeDouble(value0-level0,this.m_digits)<0)
return LINE_STATE_CROSS_DOWN;
//--- Линия коснулась уровня снизу (value1<level0 && 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_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);
//--- Линия находится под уровнем (value1<level && value0<level0)
if(::NormalizeDouble(value1-level,this.m_digits)<0 && ::NormalizeDouble(value0-level0,this.m_digits)<0)
return LINE_STATE_BELOW;
//--- Линия находится над уровнем (value1>level && 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<level0)
if(::NormalizeDouble(value1-level,this.m_digits)>=0 && ::NormalizeDouble(value0-level0,this.m_digits)<0)
return LINE_STATE_CROSS_DOWN;
//--- Линия коснулась уровня снизу (value1<level0 && 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_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 &param[] // массив параметров пользовательского индикатора
) : 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<total;i++)
{
this.m_param[i+1].type=param[i].type;
this.m_param[i+1].double_value=param[i].double_value;
this.m_param[i+1].integer_value=param[i].integer_value;
this.m_param[i+1].string_value=param[i].string_value;
}
//--- Создаём описание параметров.
//--- Если символ или период графика не текущие, то к параметрам добавляются их описания
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(name);
this.SetDescription(name);
this.m_title=this.Name()+this.Parameters();
this.m_category=IND_CATEGORY_CUSTOM;
//--- Записываем описание первого буфера линии
this.SetBufferDescription(0,this.m_title);
//--- Устанавливаем количество баров, необходимое для расчёта индикатора на текущем тике
this.SetBarsToCalculate(bars_to_calculate);
}
}
};
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Класс-коллекция индикаторов |
//+------------------------------------------------------------------+
#include <Arrays\ArrayObj.mqh>
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 &param[]); // Массив параметров
//--- Таймер
void OnTimer(void)
{
//--- В цикле по всем индикаторам коллекции
int total=this.m_list.Total();
for(int i=0;i<total;i++)
{
//--- получаем указатель на очередной объект-индикатор
//--- и вызываем его таймер
CIndMSTF *obj=this.m_list.At(i);
if(obj!=NULL)
obj.OnTimer();
}
}
//--- Конструктор/Деструктор
CMSTFIndicators(void){ this.m_list.Clear(); }
~CMSTFIndicators(void){;}
};
//+------------------------------------------------------------------+
//| Создаёт расчётную часть индикатора для переданного объекта |
//+------------------------------------------------------------------+
bool CMSTFIndicators::CreateIndicator(CIndMSTF *ind_obj)
{
//--- Если расчётную часть индикатора создать не удалось
if(!ind_obj.CreateIndicator())
{
//--- ищем индекс объекта-индикатора в списке коллекции
//--- и по полученному индексу удаляем объект-индикатор из списка коллекции
this.m_list.Sort();
int index=this.m_list.Search(ind_obj);
this.m_list.Delete(index);
//--- Возвращаем false
return false;
}
//--- Расчётная часть успешно создана - возвращаем true
return true;
}
//+------------------------------------------------------------------+
//| Возвращает объект индикатора по хэндлу расчётной части |
//+------------------------------------------------------------------+
CIndMSTF *CMSTFIndicators::GetIndicatorObj(const int ind_handle,const string source) const
{
//--- Если в метод передан невалидный хэндл - сообщаем об это и возвращаем NULL
if(ind_handle==INVALID_HANDLE)
{
::PrintFormat("%s: Error handle",source);
return NULL;
}
//--- В цикле по всем объектам-индикаторам в списке коллекции
int total=this.m_list.Total();
for(int i=0;i<total;i++)
{
//--- получаем указатель на очередной объект-индикатор
CIndMSTF *obj=this.m_list.At(i);
if(obj==NULL)
continue;
//--- Если хэндл индикатора равен переданному в метод -
//--- возвращаем указатель на найденный объект-индикатор
if(obj.Handle()==ind_handle)
return obj;
}
//--- Ничего не нашли - возвращаем NULL
return NULL;
}
//+------------------------------------------------------------------+
//| Заполняет данными буферы индикатора по хэндлу |
//+------------------------------------------------------------------+
bool CMSTFIndicators::Calculate(const int ind_handle)
{
//--- Получаем по хэндлу указатель на объект-индикатор
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
return false;
//--- Возвращаем результат работы метода Calculate полученн6ого по хэндлу объекта-индикатора
return obj.Calculate();
}
//+------------------------------------------------------------------+
//| Заполняет данными буферы всех индикаторов в коллекции |
//+------------------------------------------------------------------+
bool CMSTFIndicators::Calculate(void)
{
//--- Объявляем переменную для хранения результата
bool res=true;
//--- В цикле по всем объектам-индикаторам в списке коллекции
int total=this.m_list.Total();
for(int i=0;i<total;i++)
{
//--- получаем указатель на очередной объект-индикатор
CIndMSTF *obj=this.m_list.At(i);
if(obj==NULL)
continue;
//--- Добавляем к переменной res результат вызова метода Calculate очередного объекта-индикатора
res &=obj.Calculate();
//--- Если метод отработал с ошибкой - сообщаем об этом в журнал
if(!res)
::PrintFormat("%s::%s: Error in indicator calculation: %s",__FUNCTION__,obj.Title(),TypeErrorcDescription(obj.TypeError()));
}
//--- Если общий результат false - сообщаем об этом в журнал
if(!res)
::PrintFormat("%s: Not all indicators have been calculated successfully. It is necessary to recalculate the buffers of all indicators",__FUNCTION__);
//--- Возвращаем результат вызова методов Calculate всех индикаторов в коллекции
return res;
}
//+------------------------------------------------------------------+
//| Возвращает данные индикатора по хэндлу |
//| из указанного буфера по индексу как есть |
//+------------------------------------------------------------------+
double CMSTFIndicators::GetData(const int ind_handle,const uint buffer_num,const uint array_num,const uint index)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return EMPTY_VALUE;
}
//--- Возвращаем данные из указанного буфера индикатора по индексу, переданному в метод
return obj.GetData(buffer_num,array_num,index);
}
//+------------------------------------------------------------------+
//| Возвращает данные индикатора по хэндлу |
//| из указанного буфера по индексу на указанный символ/таймфрейм |
//+------------------------------------------------------------------+
double CMSTFIndicators::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)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return EMPTY_VALUE;
}
//--- Возвращаем данные из указанного буфера индикатора по индексу, переданному в метод
return obj.GetDataTo(symbol_to,timeframe_to,buffer_num,array_num,index);
}
//+------------------------------------------------------------------+
//| Возвращает данные индексов цвета индикатора по хэндлу |
//| из указанного буфера по индексу как есть |
//+------------------------------------------------------------------+
double CMSTFIndicators::GetColorData(const int ind_handle,const uint buffer_num,const uint index)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return EMPTY_VALUE;
}
//--- Возвращаем данные индекса цвета из указанного буфера индикатора по индексу, переданному в метод
return obj.GetColorData(buffer_num,index);
}
//+------------------------------------------------------------------+
//| Возвращает данные индексов цвета индикатора по хэндлу |
//| из указанного буфера по индексу на указанный символ/таймфрейм |
//+------------------------------------------------------------------+
double CMSTFIndicators::GetColorDataTo(const string symbol_to,const ENUM_TIMEFRAMES timeframe_to,const int ind_handle,const uint buffer_num,const uint index)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return EMPTY_VALUE;
}
//--- Возвращаем данные индекса цвета из указанного буфера индикатора по индексу, переданному в метод
return obj.GetColorDataTo(symbol_to,timeframe_to,buffer_num,index);
}
//+------------------------------------------------------------------+
//| Заполняет переданный буфер индикатора данными |
//+------------------------------------------------------------------+
bool CMSTFIndicators::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[])
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return false;
}
//--- Заполняем переданный в метод массив-буфер из указанного буфера индикатора
return obj.DataToBuffer(symbol_to,timeframe_to,buffer_num,array_num,limit,buffer);
}
//+------------------------------------------------------------------+
//| Заполняет переданный цветной буфер индикатора данными |
//+------------------------------------------------------------------+
bool CMSTFIndicators::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[])
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return false;
}
//--- Заполняем переданный в метод цветной массив-буфер из указанного цветного буфера индикатора
return obj.DataToColorBuffer(symbol_to,timeframe_to,buffer_num,array_num,limit,plot_buffer,color_buffer);
}
//+------------------------------------------------------------------+
//| Устанавливает указанное описание для линии буфера |
//+------------------------------------------------------------------+
void CMSTFIndicators::SetPlotLabel(const uint plot_index,const string descript)
{
::PlotIndexSetString(plot_index,PLOT_LABEL,descript);
}
//+------------------------------------------------------------------+
//| Устанавливает описание по умолчанию линии буфера |
//+------------------------------------------------------------------+
void CMSTFIndicators::SetPlotLabelFromBuffer(const uint plot_index,const int ind_handle,const uint buffer_num)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return;
}
//--- Устанавливаем в указанный рисуемый буфер описание указанного буфера индикатора
::PlotIndexSetString(plot_index,PLOT_LABEL,obj.BufferDescription(buffer_num));
}
//+------------------------------------------------------------------+
//| Устанавливает цвета линии буфера индикатора |
//+------------------------------------------------------------------+
void CMSTFIndicators::SetPlotColorsFromBuffer(const uint plot_index,const int ind_handle,const uint buffer_num)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return;
}
//--- Устанавливаем в указанный рисуемый буфер цвета указанного цветного буфера индикатора
uint colors=obj.ColorsTotal(buffer_num);
if(colors==0)
return;
::PlotIndexSetInteger(plot_index,PLOT_COLOR_INDEXES,colors);
for(int i=0;i<(int)colors;i++)
::PlotIndexSetInteger(plot_index,PLOT_LINE_COLOR,i,obj.BufferColorByIndex(buffer_num,(uchar)i));
}
//+------------------------------------------------------------------+
//| Устанавливает смещение указанному рисуемому буферу |
//+------------------------------------------------------------------+
void CMSTFIndicators::SetPlotShift(const uint plot_index,const int shift)
{
::PlotIndexSetInteger(plot_index,PLOT_SHIFT,shift);
}
//+------------------------------------------------------------------+
//| Возвращает описание указанного буфера |
//| указанного по хэндлу индикатора |
//+------------------------------------------------------------------+
string CMSTFIndicators::BufferDescription(const int ind_handle,const uint buffer_num)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
//--- Если указатель на объект получен - возвращаем из него описание указанного буфера. Иначе - текст ошибки
return(obj!=NULL ? obj.BufferDescription(buffer_num) : ::StringFormat("%s: Failed to get indicator object",__FUNCTION__));
}
//+------------------------------------------------------------------+
//| Устанавливает инициализирующее значение указанного буфера |
//| указанного по хэндлу индикатора |
//+------------------------------------------------------------------+
void CMSTFIndicators::SetBufferInitValue(const int ind_handle,const uint buffer_num,const double value)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return;
}
//--- Устанавливаем для указанного буфера указанное инициализирующее "пустое" значение
obj.SetBufferInitValue(buffer_num,value);
}
//+------------------------------------------------------------------+
//| Возвращает инициализирующее значение указанного буфера |
//| указанного по хэндлу индикатора |
//+------------------------------------------------------------------+
double CMSTFIndicators::BufferInitValue(const int ind_handle,const uint buffer_num) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return WRONG_VALUE;
}
//--- Возвращаем инициализирующее "пустое" значение, установленное для указанного буфера
return obj.BufferInitValue(buffer_num);
}
//+------------------------------------------------------------------+
//| Устанавливает инициализирующее значение индекса цвета |
//| для указанного буфера указанного по хэндлу индикатора |
//+------------------------------------------------------------------+
void CMSTFIndicators::SetBufferInitColorIndex(const int ind_handle,const uint buffer_num,const uchar index)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return;
}
//--- Устанавливаем для указанного буфера инициализирующее значение индекса цвета
obj.SetBufferInitColorIndex(buffer_num,index);
}
//+------------------------------------------------------------------+
//| Возвращает инициализирующее значение индекса цвета |
//| для указанного буфера указанного по хэндлу индикатора |
//+------------------------------------------------------------------+
uchar CMSTFIndicators::BufferInitColorIndex(const int ind_handle,const uint buffer_num) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return WRONG_VALUE;
}
//--- Возвращаем инициализирующее значение индекса цвета, установленное для указанного буфера
return obj.BufferInitColorIndex(buffer_num);
}
//+------------------------------------------------------------------+
//| Устанавливает значение цвета по индексу для указанного буфера |
//| указанного по хэндлу индикатора |
//+------------------------------------------------------------------+
void CMSTFIndicators::SetBufferColorToIndex(const int ind_handle,const uint buffer_num,const uchar color_idx,const color clr)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return;
}
//--- Устанавливаем для указанного буфера значение цвета по индексу
obj.SetBufferColorToIndex(buffer_num,color_idx,clr);
}
//+------------------------------------------------------------------+
//| Возвращает значение цвета по индексу для указанного буфера |
//| указанного по хэндлу индикатора |
//+------------------------------------------------------------------+
color CMSTFIndicators::BufferColorByIndex(const int ind_handle,const uint buffer_num,const uchar color_idx) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return WRONG_VALUE;
}
//--- Возвращаем значение цвета по индексу, установленное для указанного буфера
return obj.BufferColorByIndex(buffer_num,color_idx);
}
//+------------------------------------------------------------------+
//| Возвращает флаг цветности указанного буфера |
//| указанного по хэндлу индикатора |
//+------------------------------------------------------------------+
bool CMSTFIndicators::IsColoredBuffer(const int ind_handle,const uint buffer_num) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return false;
}
//--- Возвращаем значение флаг цветности, установленный для указанного буфера
return obj.IsColoredBuffer(buffer_num);
}
//+------------------------------------------------------------------+
//| Возвращает состояние данных линии указанного буфера |
//| указанного по хэндлу индикатора на указанном баре |
//+------------------------------------------------------------------+
ENUM_LINE_STATE CMSTFIndicators::BufferLineState(const int ind_handle,const uint buffer_num,const uint array_num,const int index)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return LINE_STATE_NONE;
}
//--- Возвращаем состояние линии указанного буфера на указанном индексе
return obj.BufferLineState(buffer_num,array_num,index);
}
//+------------------------------------------------------------------+
//| Возвращает состояние данных линии указанного буфера |
//| указанного по хэндлу индикатора на баре символа/таймфрейма |
//+------------------------------------------------------------------+
ENUM_LINE_STATE CMSTFIndicators::BufferLineState(const string symbol,const ENUM_TIMEFRAMES timeframe,const int ind_handle,const uint buffer_num,const uint array_num,const int index)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return LINE_STATE_NONE;
}
//--- Получаем время бара, переданного в метод
datetime array[1];
if(::CopyTime(symbol,timeframe,index,1,array)!=1)
{
::PrintFormat("%s::%s: Failed to get the time of the bar with index %ld. Error %lu",__FUNCTION__,obj.Title(),index,::GetLastError());
return LINE_STATE_NONE;
}
//--- Получаем номер бара в буфере объекта-индикатора, соответствующий найденному времени
int bar=::iBarShift(obj.Symbol(),obj.Timeframe(),array[0]);
//--- Если бар получен - возвращаем состояние линии на найденном баре, иначе - неопределённое состояние
return(bar!=WRONG_VALUE ? obj.BufferLineState(buffer_num,array_num,bar) : LINE_STATE_NONE);
}
//+------------------------------------------------------------------+
//| Возвращает соотношение данных линии указанного буфера |
//| указанного по хэндлу индикатора на указанном баре |
//| с указанными значениями |
//+------------------------------------------------------------------+
ENUM_LINE_STATE CMSTFIndicators::BufferLineStateRelative(const int ind_handle,const int buffer_num,const uint array_num,const int index,const double level0,const double level1=EMPTY_VALUE)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return LINE_STATE_NONE;
}
//--- Возвращаем соотношение линии индикатора и уровня в указанном буфере на указанном индексе
return obj.BufferLineStateRelative(buffer_num,array_num,index,level0,level1);
}
//+------------------------------------------------------------------+
//| Возвращает соотношение данных линии указанного буфера |
//| указанного по хэндлу индикатора на указанном баре |
//| с указанными значениями на указанном символе/периоде графика |
//+------------------------------------------------------------------+
ENUM_LINE_STATE CMSTFIndicators::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)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return LINE_STATE_NONE;
}
//--- Возвращаем соотношение линии индикатора и уровня в указанном буфере на указанном индексе
return obj.BufferLineStateRelative(symbol,timeframe,buffer_num,array_num,index,level0,level1);
}
//+------------------------------------------------------------------+
//| Возвращает описание категории |
//+------------------------------------------------------------------+
string CMSTFIndicators::CategoryDescription(const int ind_handle)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
//--- Если объект получен, возвращаем описание категории. Иначе - текст ошибки
return(obj!=NULL ? obj.CategoryDescription() : ::StringFormat("%s: Failed to get indicator object",__FUNCTION__));
}
//+------------------------------------------------------------------+
//| Устанавливает идентификатор |
//+------------------------------------------------------------------+
void CMSTFIndicators::SetID(const int ind_handle,const int id)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return;
}
//--- Устанавливаем идентификатор для полученного объекта
obj.SetID(id);
}
//+------------------------------------------------------------------+
//| Устанавливает Digits индикатора |
//+------------------------------------------------------------------+
void CMSTFIndicators::SetDigits(const int ind_handle,const int digits)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return;
}
//--- Устанавливаем Digits для полученного объекта
obj.SetDigits(digits);
}
//+------------------------------------------------------------------+
//| Устанавливает пользовательское описание |
//+------------------------------------------------------------------+
void CMSTFIndicators::SetDescription(const int ind_handle,const string descr)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return;
}
//--- Устанавливаем описание для полученного объекта
obj.SetDescription(descr);
}
//+------------------------------------------------------------------+
//| Устанавливает описание указанного буфера |
//+------------------------------------------------------------------+
void CMSTFIndicators::SetBufferDescription(const int ind_handle,const uint buffer_num,const string descr)
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return;
}
//--- Устанавливаем описание для указанного буфера полученного объекта
obj.SetBufferDescription(buffer_num,descr);
}
//+------------------------------------------------------------------+
//| Возвращает флаг серийности указанного буфера |
//+------------------------------------------------------------------+
bool CMSTFIndicators::IsSeries(const int ind_handle,const uint buffer_num,const uint array_num) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return false;
}
//--- Возвращаем флаг серийности указанного буфера полученного объекта
return obj.IsSeries(buffer_num,array_num);
}
//+------------------------------------------------------------------+
//| Возвращает флаг синхронизированности |
//| исторических данных по символу/периоду |
//+------------------------------------------------------------------+
bool CMSTFIndicators::IsSynchronized(const int ind_handle) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return false;
}
//--- Возвращаем флаг синхронизированности полученного объекта
return obj.IsSynchronized();
}
//+------------------------------------------------------------------+
//| Возвращает таймфрейм указанного индикатора |
//+------------------------------------------------------------------+
ENUM_TIMEFRAMES CMSTFIndicators::Timeframe(const int ind_handle) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return WRONG_VALUE;
}
//--- Возвращаем таймфрейм полученного объекта
return obj.Timeframe();
}
//+------------------------------------------------------------------+
//| Возвращает символ указанного индикатора |
//+------------------------------------------------------------------+
string CMSTFIndicators::Symbol(const int ind_handle) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
//--- Если объект получен, возвращаем наименование символа. Иначе - текст ошибки
return(obj!=NULL ? obj.Symbol() : ::StringFormat("%s: Failed to get indicator object",__FUNCTION__));
}
//+------------------------------------------------------------------+
//| Возвращает наименование указанного индикатора |
//+------------------------------------------------------------------+
string CMSTFIndicators::Name(const int ind_handle) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
//--- Если объект получен, возвращаем наименование индикатора. Иначе - текст ошибки
return(obj!=NULL ? obj.Name() : ::StringFormat("%s: Failed to get indicator object",__FUNCTION__));
}
//+------------------------------------------------------------------+
//| Возвращает список параметров указанного индикатора |
//+------------------------------------------------------------------+
string CMSTFIndicators::Parameters(const int ind_handle) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
//--- Если объект получен, возвращаем список параметров индикатора. Иначе - текст ошибки
return(obj!=NULL ? obj.Parameters() : ::StringFormat("%s: Failed to get indicator object",__FUNCTION__));
}
//+------------------------------------------------------------------+
//| Возвращает Digits указанного индикатора |
//+------------------------------------------------------------------+
int CMSTFIndicators::Digits(const int ind_handle) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return WRONG_VALUE;
}
//--- Возвращаем Digits полученного объекта
return obj.Digits();
}
//+------------------------------------------------------------------+
//| Возвращает количество буферов указанного индикатора |
//+------------------------------------------------------------------+
uint CMSTFIndicators::BuffersTotal(const int ind_handle) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return 0;
}
//--- Возвращаем количество буферов полученного объекта
return obj.BuffersTotal();
}
//+------------------------------------------------------------------+
//| Возвращает количество баров таймсерии для указанного индикатора |
//+------------------------------------------------------------------+
uint CMSTFIndicators::RatesTotal(const int ind_handle) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return 0;
}
//--- Возвращаем количество баров таймсерии полученного объекта
return obj.RatesTotal();
}
//+------------------------------------------------------------------+
//| Возвращает идентификатор указанного индикатора |
//+------------------------------------------------------------------+
int CMSTFIndicators::ID(const int ind_handle) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return WRONG_VALUE;
}
//--- Возвращаем идентификатор полученного объекта
return obj.ID();
}
//+------------------------------------------------------------------+
//| Возвращает описание указанного индикатора |
//+------------------------------------------------------------------+
string CMSTFIndicators::Description(const int ind_handle) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
//--- Если объект получен, возвращаем описание индикатора. Иначе - текст ошибки
return(obj!=NULL ? obj.Description() : ::StringFormat("%s: Failed to get indicator object",__FUNCTION__));
}
//+------------------------------------------------------------------+
//| Возвращает заголовок указанного индикатора |
//+------------------------------------------------------------------+
string CMSTFIndicators::Title(const int ind_handle) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
//--- Если объект получен, возвращаем заголовок индикатора. Иначе - текст ошибки
return(obj!=NULL ? obj.Title() : ::StringFormat("%s: Failed to get indicator object",__FUNCTION__));
}
//+------------------------------------------------------------------+
//| Возвращает категорию указанного индикатора |
//+------------------------------------------------------------------+
ENUM_IND_CATEGORY CMSTFIndicators::Category(const int ind_handle) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return IND_CATEGORY_NONE;
}
//--- Возвращаем категорию полученного объекта
return obj.Category();
}
//+------------------------------------------------------------------+
//| Возвращает количество параметров указанного индикатора |
//+------------------------------------------------------------------+
uint CMSTFIndicators::ParamsTotal(const int ind_handle) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return 0;
}
//--- Возвращаем количество параметров полученного объекта
return obj.ParamsTotal();
}
//+------------------------------------------------------------------+
//| Возвращает структуру параметров по индексу из массива |
//| для указанного индикатора |
//+------------------------------------------------------------------+
MqlParam CMSTFIndicators::GetMqlParam(const int ind_handle,const int index) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
MqlParam null;
::ZeroMemory(null);
return null;
}
//--- Возвращаем структуру параметров полученного объекта по индексу из массива параметров
return obj.GetMqlParam(index);
}
//+------------------------------------------------------------------+
//| Возвращает описание таймфрейма для указанного индикатора |
//+------------------------------------------------------------------+
string CMSTFIndicators::TimeframeDescription(const int ind_handle) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
//--- Если объект получен, возвращаем описание таймфрейма индикатора. Иначе - текст ошибки
return(obj!=NULL ? obj.Description() : ::StringFormat("%s: Failed to get indicator object",__FUNCTION__));
}
//+------------------------------------------------------------------+
//| Возвращает количество рассчитанных данных указанного индикатора |
//+------------------------------------------------------------------+
int CMSTFIndicators::Calculated(const int ind_handle) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return WRONG_VALUE;
}
//--- Возвращаем количество рассчитанных данных полученного объекта
return obj.Calculated();
}
//+------------------------------------------------------------------+
//| Возвращает тип указанного индикатора |
//+------------------------------------------------------------------+
ENUM_INDICATOR CMSTFIndicators::Type(const int ind_handle) const
{
//--- Получаем указатель на объект-индикатор по хэндлу, переданному в метод
CIndMSTF *obj=this.GetIndicatorObj(ind_handle,__FUNCTION__);
if(obj==NULL)
{
::PrintFormat("%s: Failed to get indicator object",__FUNCTION__);
return (ENUM_INDICATOR)WRONG_VALUE;
}
//--- Возвращаем тип индикатора полученного объекта
return (ENUM_INDICATOR)obj.Type();
}
//+------------------------------------------------------------------+
//| Добавляет указанный индикатор в коллекцию |
//+------------------------------------------------------------------+
int CMSTFIndicators::AddNewIndicator(CIndMSTF *ind_obj,const string source)
{
//--- Устанавливаем списку коллекции флаг сортированного списка
this.m_list.Sort();
//--- Ищем в списке индекс аналогичного переданному в метод объекта-индикатора
int index=this.m_list.Search(ind_obj);
//--- Если такой индикатор с такими же параметрами уже есть в списке,
if(index>WRONG_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 &param[])
{
//--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем 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__);
}
//+------------------------------------------------------------------+