186 lines
No EOL
15 KiB
MQL5
186 lines
No EOL
15 KiB
MQL5
//--- Связь с основным файлом индикатора
|
|
//#include "..\MultiSymbolPriceDivergence.mq5"
|
|
//--- Подключаем свои библиотеки
|
|
#include "Checks.mqh"
|
|
#include "SetDeleteObjects.mqh"
|
|
//+------------------------------------------------------------------+
|
|
//| Установим свойства окна |
|
|
//+------------------------------------------------------------------+
|
|
void SetSubwindowProperties()
|
|
{
|
|
//--- Получим номер окна индикатора
|
|
number_window=ChartWindowFind(0,shortname_indicator);
|
|
//--- Получим ширину и высоту подокна
|
|
chart_width=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS);
|
|
chart_height=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,number_window);
|
|
//--- Получим центр окна графика
|
|
chart_wcenter=chart_width/2;
|
|
chart_vcenter=chart_height/2;
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Установим цвета баров текущего символа |
|
|
//+------------------------------------------------------------------+
|
|
void SetBarColors()
|
|
{
|
|
//--- Цвет бара вверх, тени и окантовки тела бычьей свечи
|
|
ChartSetInteger(0,CHART_COLOR_CHART_UP,color_bar_up);
|
|
//--- Цвет тела бычьей свечи
|
|
ChartSetInteger(0,CHART_COLOR_CANDLE_BULL,color_bar_up);
|
|
//--- Цвет линии графика и японских свечей "Доджи"
|
|
ChartSetInteger(0,CHART_COLOR_CHART_LINE,color_bar_up);
|
|
//--- Если включен двухцветный режим
|
|
if(TwoColor)
|
|
{
|
|
//--- Цвет бара вниз, тени и окантовки тела медвежьей свечи
|
|
ChartSetInteger(0,CHART_COLOR_CHART_DOWN,color_bar_down);
|
|
//--- Цвет тела медвежьей свечи
|
|
ChartSetInteger(0,CHART_COLOR_CANDLE_BEAR,color_bar_down);
|
|
}
|
|
//--- Если двухцветный режим отключен
|
|
else
|
|
{
|
|
//--- Цвет бара вниз, тени и окантовки тела медвежьей свечи
|
|
ChartSetInteger(0,CHART_COLOR_CHART_DOWN,color_bar_up);
|
|
//--- Цвет тела медвежьей свечи
|
|
ChartSetInteger(0,CHART_COLOR_CANDLE_BEAR,color_bar_up);
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Корректирует максимум/минимум графика относительно всех буферов |
|
|
//+------------------------------------------------------------------+
|
|
void CorrectMaximumMinimumChart()
|
|
{
|
|
double low[]; // Массив минимумов
|
|
double high[]; // Массив максимумов
|
|
int try =10; // Кол-во попыток
|
|
int size_array =0; // Размер массива для рисования
|
|
int visible_bars =0; // Количество видимых баров
|
|
int first_visible_bar =0; // Номер первого видимого бара
|
|
int last_visible_bar =0; // Номер последнего видимого бара
|
|
double max_price =0.0; // Максимальная цена
|
|
double min_price =0.0; // Минимальная цена
|
|
double offset_max_min =0.0; // Отступ от максимума/минимума графика
|
|
//--- Обнулим последнюю ошибку
|
|
ResetLastError();
|
|
//--- Количество видимых баров
|
|
visible_bars=(int)ChartGetInteger(0,CHART_VISIBLE_BARS);
|
|
//--- Номер первого видимого бара
|
|
first_visible_bar=(int)ChartGetInteger(0,CHART_FIRST_VISIBLE_BAR);
|
|
//--- Номер последнего видимого бара
|
|
last_visible_bar=first_visible_bar-visible_bars;
|
|
//--- Если есть ошибка, выйдем
|
|
if(GetLastError()!=0)
|
|
return;
|
|
//--- Если значение некорректно, исправим
|
|
if(last_visible_bar<0)
|
|
last_visible_bar=0;
|
|
//--- Получим максимум и минимум текущего символа на видимой части графика
|
|
for(int i=0; i<try; i++)
|
|
if(CopyHigh(Symbol(),Period(),last_visible_bar,visible_bars,high)==visible_bars)
|
|
break;
|
|
for(int i=0; i<try; i++)
|
|
if(CopyLow(Symbol(),Period(),last_visible_bar,visible_bars,low)==visible_bars)
|
|
break;
|
|
//--- Выйдем, если данные не были получены
|
|
if(ArraySize(high)<=0 || ArraySize(low)<=0)
|
|
return;
|
|
//--- Если данные получены, то
|
|
// определим в массивах текущего символа максимум и минимум
|
|
else
|
|
{
|
|
min_price=low[ArrayMinimum(low)];
|
|
max_price=high[ArrayMaximum(high)];
|
|
}
|
|
//--- Получим максимальную и минимальную цены на всех ценовых массивах
|
|
for(int s=0; s<SYMBOLS; s++)
|
|
{
|
|
//--- Если такого символа нет, то перейти к следующему
|
|
if(symbols_names[s]==empty_symbol)
|
|
continue;
|
|
//---
|
|
datetime time[]; // Массив времени
|
|
int number_bars =0; // Количество баров для расчёта
|
|
//--- Установим нулевой размер массивам
|
|
ArrayResize(high,0);
|
|
ArrayResize(low,0);
|
|
//--- Получим время первого видимого на графике бара
|
|
for(int i=0; i<try; i++)
|
|
if(CopyTime(Symbol(),Period(),last_visible_bar,visible_bars,time)==visible_bars)
|
|
break;
|
|
//--- Если данных меньше, чем видимых баров на графике, выйдем
|
|
if(ArraySize(time)<visible_bars)
|
|
return;
|
|
//--- Если время первого "истинного" бара больше, чем
|
|
// время первого видимого бара на графике, то
|
|
// получим доступное количество баров текущего в цикле символа
|
|
if(limit_time[s]>time[0])
|
|
{
|
|
//--- Получим размер массива
|
|
size_array=ArraySize(time);
|
|
//--- Получим количество баров от первого истинного
|
|
if((number_bars=Bars(Symbol(),Period(),limit_time[s],time[size_array-1]))<=0)
|
|
return;
|
|
}
|
|
//--- Иначе получим видимое количество баров на графике
|
|
else
|
|
number_bars=visible_bars;
|
|
//--- Установим индексацию, как в таймсериях
|
|
ArraySetAsSeries(low,true);
|
|
ArraySetAsSeries(high,true);
|
|
//--- Скопируем данные из индикаторных буферов
|
|
// Все режимы кроме Линия
|
|
if(DrawType!=LINES)
|
|
{
|
|
ArrayCopy(low,buffer_data[s].low);
|
|
ArrayCopy(high,buffer_data[s].high);
|
|
}
|
|
//--- Если в режиме Линия
|
|
else
|
|
{
|
|
ArrayCopy(low,buffer_data[s].close);
|
|
ArrayCopy(high,buffer_data[s].close);
|
|
}
|
|
//--- Получим размер массива
|
|
size_array=ArraySize(high);
|
|
//--- Заполним пустые значения,
|
|
// чтобы они не учитывались в определении максимума/минимума
|
|
for(int i=0; i<size_array; i++)
|
|
{
|
|
if(high[i]==EMPTY_VALUE)
|
|
high[i]=max_price;
|
|
if(low[i]==EMPTY_VALUE)
|
|
low[i]=min_price;
|
|
}
|
|
//--- Определим максимум/минимум учитывая инверсию
|
|
if(inverse[s])
|
|
{
|
|
//--- Если ошибок нет, запомним значения
|
|
if(ArrayMaximum(high,last_visible_bar,number_bars)>=0 &&
|
|
ArrayMinimum(low,last_visible_bar,number_bars)>=0)
|
|
{
|
|
max_price=fmax(max_price,low[ArrayMaximum(low,last_visible_bar,number_bars)]);
|
|
min_price=fmin(min_price,high[ArrayMinimum(high,last_visible_bar,number_bars)]);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//--- Если ошибок нет, запомним значения
|
|
if(ArrayMinimum(low,last_visible_bar,number_bars)>=0 &&
|
|
ArrayMaximum(high,last_visible_bar,number_bars)>=0)
|
|
{
|
|
min_price=fmin(min_price,low[ArrayMinimum(low,last_visible_bar,number_bars)]);
|
|
max_price=fmax(max_price,high[ArrayMaximum(high,last_visible_bar,number_bars)]);
|
|
}
|
|
}
|
|
}
|
|
//--- Рассчитаем отступ (3%) от верха и низа графика
|
|
offset_max_min=((max_price-min_price)*3)/100;
|
|
//--- Включим режим фиксированного масштаба графика
|
|
ChartSetInteger(0,CHART_SCALEFIX,true);
|
|
//--- Установим максимум/минимум
|
|
ChartSetDouble(0,CHART_FIXED_MAX,max_price+offset_max_min);
|
|
ChartSetDouble(0,CHART_FIXED_MIN,min_price-offset_max_min);
|
|
//--- Обновим график
|
|
ChartRedraw();
|
|
}
|
|
//+------------------------------------------------------------------+ |