6004 lines
No EOL
647 KiB
MQL5
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 ¶m[] // массив параметров пользовательского индикатора
|
|
) : CIndMSTF(IND_CUSTOM,buffers,symbol,timeframe)
|
|
{
|
|
//--- Если передан пустой массив параметров - сообщаем об этом в журнал
|
|
int total=(int)param.Size();
|
|
if(total==0)
|
|
::PrintFormat("%s Error. Passed an empty array",__FUNCTION__);
|
|
//--- Если массив не пустой и его размер увеличен на 1 (в первый параметр типа string должно быть записано имя индикатора)
|
|
ResetLastError();
|
|
if(total>0 && ::ArrayResize(this.m_param,total+1)==total+1)
|
|
{
|
|
//--- Обнуляем данные в массиве и вписываем имя (путь к файлу и имя .ex5 файла)
|
|
::ZeroMemory(this.m_param);
|
|
//--- имя пользовательского индикатора
|
|
this.m_param[0].type=TYPE_STRING;
|
|
this.m_param[0].string_value=path;
|
|
//--- заполняем массив параметров индикатора
|
|
for(int i=0;i<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 ¶m[]); // Массив параметров
|
|
//--- Таймер
|
|
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 ¶m[])
|
|
{
|
|
//--- Создаём новый объект индикатора. При ошибке сообщаем об этом в журнал и возвращаем INVALID_HANDLE
|
|
CIndCustom *ind_obj=new CIndCustom(symbol,timeframe,path,name,buffers,bars_to_calculate,param);
|
|
if(ind_obj==NULL)
|
|
{
|
|
::PrintFormat("%s: Error. Failed to create %s custom indicator object",__FUNCTION__,name);
|
|
return INVALID_HANDLE;
|
|
}
|
|
//--- Возвращаем результат добавления созданного объекта-индикатора в список коллекцию
|
|
return this.AddNewIndicator(ind_obj,__FUNCTION__);
|
|
}
|
|
//+------------------------------------------------------------------+ |