//+------------------------------------------------------------------+ //| ChartObjects.mq5 | //| Copyright 2013, MetaQuotes Software Corp. | //| http://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2013, MetaQuotes Software Corp." #property link "http://www.mql5.com" #property version "1.00" //--- #property indicator_chart_window // Индикатор в главном окне #property indicator_plots 0 // Ноль серий для отрисовки //--- Подключаемый ресурс-индикатор #resource "\\Indicators\\SubWindow.ex5" //--- Количество кнопок-таймфреймов #define TIMEFRAME_BUTTONS 21 //--- Количество кнопок для свойств объекта-графика #define PROPERTY_BUTTONS 5 //--- Путь к индикатору SubWindow из ресурса string subwindow_path ="::Indicators\\SubWindow.ex5"; int subwindow_number =-1; // Номер подокна int subwindow_handle =INVALID_HANDLE; // Хэндл индикатора SubWindow string subwindow_shortname ="SubWindow"; // Короткое имя индикатора //--- int chart_width =0; // Ширина графика int chart_height =0; // Высота графика int chart_scale =0; // Масштаб графика //--- color cOffButtonFont =clrWhite; // Цвет текста в отжатой кнопке color cOffButtonBackground =clrDarkSlateGray; // Цвет фона в отжатой кнопке color cOffButtonBorder =clrLightGray; // Цвет рамки в отжатой кнопке //--- color cOnButtonFont =clrGold; // Цвет текста в нажатой кнопке color cOnButtonBackground =C'28,47,47'; // Цвет фона в нажатой кнопке color cOnButtonBorder =clrLightGray; // Цвет рамки в нажатой кнопке //--- Массив с именами объектов для кнопок-таймфреймов string timeframe_button_names[TIMEFRAME_BUTTONS]= { "button_m1","button_m2","button_m3","button_m4","button_m5","button_m6","button_m10", "button_m12","button_m15","button_m20","button_m30","button_h1","button_h2","button_h3", "button_h4","button_h6","button_h8","button_h12","button_d1","button_w1","button_mn" }; //--- Массив с отображаемым текстом в кнопках-таймфреймах string timeframe_button_texts[TIMEFRAME_BUTTONS]= { "M1","M2","M3","M4","M5","M6","M10", "M12","M15","M20","M30","H1","H2","H3", "H4","H6","H8","H12","D1","W1","MN" }; //--- Массив состояний кнопок-таймфреймов bool timeframe_button_states[TIMEFRAME_BUTTONS]={false}; //--- Массив с именами объектов для кнопок настроек графиков string property_button_names[PROPERTY_BUTTONS]= { "property_button_date","property_button_price", "property_button_ohlc","property_button_askbid", "property_button_trade_levels" }; //--- Массив с отображаемым текстом в кнопках настроек графиков string property_button_texts[PROPERTY_BUTTONS]= { "Date","Price","OHLC","Ask / Bid","Trade Levels" }; //--- Массив состояний кнопок настроек графиков bool property_button_states[PROPERTY_BUTTONS]={false}; //--- Массив размеров кнопок настроек графиков int property_button_widths[PROPERTY_BUTTONS]= { 66,68,66,100,101 }; //--- Массив с именами объектов-графиков string chart_object_names[TIMEFRAME_BUTTONS]= { "chart_object_m1","chart_object_m2","chart_object_m3","chart_object_m4","chart_object_m5","chart_object_m6","chart_object_m10", "chart_object_m12","chart_object_m15","chart_object_m20","chart_object_m30","chart_object_h1","chart_object_h2","chart_object_h3", "chart_object_h4","chart_object_h6","chart_object_h8","chart_object_h12","chart_object_d1","chart_object_w1","chart_object_mn" }; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Добавим на график панель с кнопками-таймфреймами AddTimeframeButtons(); //--- Добавим на график панель с кнопками настроек графиков AddPropertyButtons(); //--- Перерисуем график ChartRedraw(); //--- Инициализация прошла успешно return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Деинициализация индикатора | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- Если индикатор удален с графика if(reason==REASON_REMOVE) { //--- Удалим кнопки DeleteTimeframeButtons(); DeletePropertyButtons(); //--- Перерисуем график ChartRedraw(); } } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) { //--- //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- Событие CHARTEVENT_OBJECT_CLICK if(ChartEventObjectClick(id,lparam,dparam,sparam)) return; //--- Событие CHARTEVENT_CHART_CHANGE if(ChartEventChartChange(id,lparam,dparam,sparam)) return; } //+------------------------------------------------------------------+ //| Создает объект "кнопку" | //+------------------------------------------------------------------+ void CreateButton(long chart_id, // id графика int window_number, // номер окна string name, // имя объекта string text, // отображаемое имя ENUM_ANCHOR_POINT anchor, // точка привязки ENUM_BASE_CORNER corner, // угол графика string font_name, // шрифт int font_size, // размер шрифта color font_color, // цвет шрифта color background_color, // цвет фона color border_color, // цвет рамки int x_size, // ширина int y_size, // высота int x_distance, // координата по шкале X int y_distance, // координата по шкале Y long z_order) // приоритет { //--- Если объект успешно создался if(ObjectCreate(chart_id,name,OBJ_BUTTON,window_number,0,0)) { // Установим свойства кнопки ObjectSetString(chart_id,name,OBJPROP_TEXT,text); // установка имени ObjectSetString(chart_id,name,OBJPROP_FONT,font_name); // установка шрифта ObjectSetInteger(chart_id,name,OBJPROP_COLOR,font_color); // установка цвета шрифта ObjectSetInteger(chart_id,name,OBJPROP_BGCOLOR,background_color); // установка цвета фона ObjectSetInteger(chart_id,name,OBJPROP_BORDER_COLOR,border_color); // установка цвета рамки ObjectSetInteger(chart_id,name,OBJPROP_ANCHOR,anchor); // установка точки привязки ObjectSetInteger(chart_id,name,OBJPROP_CORNER,corner); // установка угла привязки ObjectSetInteger(chart_id,name,OBJPROP_FONTSIZE,font_size); // установка размера шрифта ObjectSetInteger(chart_id,name,OBJPROP_XSIZE,x_size); // установка ширины ObjectSetInteger(chart_id,name,OBJPROP_YSIZE,y_size); // установка высоты ObjectSetInteger(chart_id,name,OBJPROP_XDISTANCE,x_distance); // установка координаты X ObjectSetInteger(chart_id,name,OBJPROP_YDISTANCE,y_distance); // установка координаты Y ObjectSetInteger(chart_id,name,OBJPROP_SELECTABLE,false); // объект недоступен для выделения ObjectSetInteger(chart_id,name,OBJPROP_STATE,false); // состояние кнопки (нажата/отжата) ObjectSetInteger(chart_id,name,OBJPROP_ZORDER,z_order); // приоритет на получение события нажатия мышью ObjectSetString(chart_id,name,OBJPROP_TOOLTIP,"\n"); // нет всплывающей подсказки } } //+------------------------------------------------------------------+ //| Создает объект "график" в подокне | //+------------------------------------------------------------------+ void CreateChartInSubwindow(int window_number, // номер подокна int x_distance, // координата X int y_distance, // координата Y int x_size, // ширина int y_size, // высота string name, // имя объекта string symbol, // символ ENUM_TIMEFRAMES timeframe, // таймфрейм int subchart_scale, // масштаб баров bool show_dates, // показывать шкалу дат bool show_prices, // показывать шкалу цен bool show_ohlc, // показывать цены OHLC bool show_ask_bid, // показывать уровни ask/bid bool show_levels, // показывать торговые уровни string tooltip) // всплывающая подсказка { //--- Если объект успешно создался if(ObjectCreate(0,name,OBJ_CHART,window_number,0,0)) { //--- Установим свойства объекта-графика ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_LEFT_UPPER); // угол привязки графика ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x_distance); // координата X ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y_distance); // координата Y ObjectSetInteger(0,name,OBJPROP_XSIZE,x_size); // ширина ObjectSetInteger(0,name,OBJPROP_YSIZE,y_size); // высота ObjectSetInteger(0,name,OBJPROP_CHART_SCALE,subchart_scale); // масштаб баров ObjectSetInteger(0,name,OBJPROP_DATE_SCALE,show_dates); // шкала дат ObjectSetInteger(0,name,OBJPROP_PRICE_SCALE,show_prices); // шкала цен ObjectSetString(0,name,OBJPROP_SYMBOL,symbol); // символ ObjectSetInteger(0,name,OBJPROP_PERIOD,timeframe); // таймфрейм ObjectSetString(0,name,OBJPROP_TOOLTIP,tooltip); // всплывающая подсказка ObjectSetInteger(0,name,OBJPROP_BACK,false); // объект на переднем плане ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false); // объект недоступен для выделения ObjectSetInteger(0,name,OBJPROP_COLOR,clrWhite); // белый цвет //--- Получим идентификатор объекта-графика long subchart_id=ObjectGetInteger(0,name,OBJPROP_CHART_ID); //--- Установим специальные свойства объекта-графика ChartSetInteger(subchart_id,CHART_SHOW_OHLC,show_ohlc); // OHLC ChartSetInteger(subchart_id,CHART_SHOW_TRADE_LEVELS,show_levels); // торговые уровни ChartSetInteger(subchart_id,CHART_SHOW_BID_LINE,show_ask_bid); // уровень bid ChartSetInteger(subchart_id,CHART_SHOW_ASK_LINE,show_ask_bid); // уровень ask ChartSetInteger(subchart_id,CHART_COLOR_LAST,clrLimeGreen); // цвет уровня последней совершенной сделки ChartSetInteger(subchart_id,CHART_COLOR_STOP_LEVEL,clrRed); // цвет уровней стоп-ордеров //--- Обновим объект-график ChartRedraw(subchart_id); } } //+------------------------------------------------------------------+ //| Добавляет кнопки-таймфреймы | //+------------------------------------------------------------------+ void AddTimeframeButtons() { int x_dist =1; // Отступ от левого края графика int y_dist =125; // Отступ от нижней части графика int x_size =28; // Ширина кнопок int y_size =20; // Высота кнопок //--- for(int i=0; i=0) { //--- Удалим его или сообщим об ошибке if(!ObjectDelete(ChartID(),object_name)) Print("Ошибка ("+IntegerToString(GetLastError())+") при удалении объекта!"); } } //+------------------------------------------------------------------+ //| Событие нажатия мышки на графическом объекте | //+------------------------------------------------------------------+ bool ChartEventObjectClick(int id, long lparam, double dparam, string sparam) { //--- Кликнули мышью на графическом объекте if(id==CHARTEVENT_OBJECT_CLICK) { //--- Если кликнули на кнопке-таймфрейме, установим/удалим окно 'SubWindow' и объект-график if(ToggleSubwindowAndChartObject(sparam)) return(true); //--- Если кликнули на кнопке настроек графиков, установим/удалим свойство в объектах-графиках if(ToggleChartObjectProperty(sparam)) return(true); } //--- return(false); } //+------------------------------------------------------------------+ //| Событие изменения свойств графика | //+------------------------------------------------------------------+ bool ChartEventChartChange(int id, long lparam, double dparam, string sparam) { //--- Изменили размеры или свойства графика if(id==CHARTEVENT_CHART_CHANGE) { //--- Если окно SubWindow удалено (или отсутствует), а кнопки таймфреймов нажаты, // то отожмем все кнопки (переустановим) if(OnSubwindowDelete()) return(true); //--- Сохраним значения высоты и ширины главного графика и подокна SubWindow, если оно есть GetSubwindowWidthAndHeight(); //--- Отрегулируем размеры объектов графиков AdjustChartObjectsSizes(); //--- Обновим график и выйдем ChartRedraw(); return(true); } //--- return(false); } //+------------------------------------------------------------------+ //| Устанавливает/удаляет подокно SubWindow и объект-график | //+------------------------------------------------------------------+ bool ToggleSubwindowAndChartObject(string clicked_object_name) { //--- Убедимся, что нажатие было на объекте кнопка-таймфрейм if(CheckClickOnTimeframeButton(clicked_object_name)) { //--- Проверим, есть ли подокно SubWindow subwindow_number=ChartWindowFind(0,subwindow_shortname); //--- Если нет подокна SubWindow, установим его if(subwindow_number<0) { //--- Если подокно SubWindow установлено if(AddSubwindow()) { //--- Установим в нем объекты-графики AddChartObjectsToSubwindow(clicked_object_name); return(true); } } //--- Если есть подокно SubWindow if(subwindow_number>0) { //--- Установим в нем объекты-графики AddChartObjectsToSubwindow(clicked_object_name); return(true); } } //--- return(false); } //+------------------------------------------------------------------+ //| Проверяет, было ли нажатие на кнопке-таймфрейме | //+------------------------------------------------------------------+ bool CheckClickOnTimeframeButton(string clicked_object_name) { //--- Пройдемся по всем кнопкам-таймфреймам и сверим имена for(int i=0; i0) { //--- Удалим его if(!ChartIndicatorDelete(0,subwindow_number,subwindow_shortname)) Print("Не удалось удалить индикатор "+subwindow_shortname+"!"); } } //+------------------------------------------------------------------+ //| Добавляет объекты-графики в подокно | //+------------------------------------------------------------------+ void AddChartObjectsToSubwindow(string clicked_object_name) { ENUM_TIMEFRAMES tf =WRONG_VALUE; // Таймфрейм string object_name =""; // Имя объекта string object_text =""; // Текст в объекте int x_distance =0; // Координата по оси X int total_charts =0; // Всего объектов-графиков int chart_object_width =0; // Ширина объекта-графика //--- Узнаем масштаб баров, высоту/ширину подокна SubWindow chart_scale=(int)ChartGetInteger(0,CHART_SCALE); chart_width=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,subwindow_number); chart_height=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,subwindow_number); //--- Получим количество объектов-графиков в подокне SubWindow total_charts=ObjectsTotal(0,subwindow_number,OBJ_CHART); //--- Если нет объектов-графиков if(total_charts==0) { //--- Проверим, было ли нажатие на кнопке-таймфрейме if(CheckClickOnTimeframeButton(clicked_object_name)) { //--- Инициализируем массив кнопок-таймфреймов InitializeTimeframeButtonStates(); //--- Получим текст в кнопке-таймфрейме для всплывающей подсказки для объекта-графика object_text=ObjectGetString(0,clicked_object_name,OBJPROP_TEXT); //--- Получим таймфрейм для объекта-графика tf=StringToTimeframe(object_text); //--- Установим объект-график CreateChartInSubwindow(subwindow_number,0,0,chart_width,chart_height, "chart_object_"+object_text,_Symbol,tf,chart_scale, property_button_states[0],property_button_states[1], property_button_states[2],property_button_states[3], property_button_states[4],object_text); //--- Обновим график и выйдем ChartRedraw(); return; } } //--- Если объекты-графики уже есть в подокне SubWindow if(total_charts>0) { //--- Получим количество нажатых кнопок-таймфреймов и проинициализируем массив состояний int pressed_buttons_count=InitializeTimeframeButtonStates(); //--- Если нет нажатых кнопок, удалим подокно SubWindow if(pressed_buttons_count==0) DeleteSubwindow(); //--- Если нажатые кнопки есть else { //--- Удалим все объекты-графики из подокна ObjectsDeleteAll(0,subwindow_number,OBJ_CHART); //--- Получим ширину для объектов-графиков chart_object_width=chart_width/pressed_buttons_count; //--- Пройдемся в цикле по всем кнопкам for(int i=0; i0) { //--- Получим кол-во объектов-графиков total_charts=ObjectsTotal(0,subwindow_number,OBJ_CHART); //--- Пройдёмся в цикле по всем объектам-графикам for(int i=0; i0) { //--- Получим кол-во объектов графиков total_charts=ObjectsTotal(0,subwindow_number,OBJ_CHART); //--- Пройдёмся в цикле по всем объектам-графикам for(int i=0; i0) { //--- Получим кол-во объектов графиков total_charts=ObjectsTotal(0,subwindow_number,OBJ_CHART); //--- Пройдёмся в цикле по всем объектам-графикам for(int i=0; i0) { //--- Получим кол-во объектов графиков total_charts=ObjectsTotal(0,subwindow_number,OBJ_CHART); //--- Пройдёмся в цикле по всем объектам-графикам for(int i=0; i0) { //--- Получим кол-во объектов графиков total_charts=ObjectsTotal(0,subwindow_number,OBJ_CHART); //--- Пройдёмся в цикле по всем объектам-графикам for(int i=0; i0) { // Получим высоту и ширину подокна chart_height=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS,subwindow_number); chart_width=(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS,subwindow_number); } } //+------------------------------------------------------------------+ //| Регулирует ширину объектов-графиков при изменении ширины окна | //+------------------------------------------------------------------+ void AdjustChartObjectsSizes() { int x_distance =0; // Координата по оси X int total_objects =0; // Количество объектов-графиков int chart_object_width =0; // Ширина объекта-графика string object_name =""; // Имя объекта ENUM_TIMEFRAMES TF =WRONG_VALUE; // Таймфрейм //--- Получим номер подокна SubWindow if((subwindow_number=ChartWindowFind(0,subwindow_shortname))>0) { //--- Получим общее количество объектов-графиков total_objects=ObjectsTotal(0,subwindow_number,OBJ_CHART); //--- Если объектов нет, то удалим подокно и выйдем if(total_objects==0) { DeleteSubwindow(); return; } //--- Получим ширину для объектов-графиков chart_object_width=chart_width/total_objects; //--- Пройдемся в цикле по всем объектам-графикам for(int i=total_objects-1; i>=0; i--) { //--- Получим имя object_name=ObjectName(0,i,subwindow_number,OBJ_CHART); //--- Установим ширину и высоту объекта-графика ObjectSetInteger(0,object_name,OBJPROP_YSIZE,chart_height); ObjectSetInteger(0,object_name,OBJPROP_XSIZE,chart_object_width); //--- Установим положение объекта-графика ObjectSetInteger(0,object_name,OBJPROP_YDISTANCE,0); ObjectSetInteger(0,object_name,OBJPROP_XDISTANCE,x_distance); //--- Установим новую координату по оси X для следующего объекта-графика x_distance+=chart_object_width; } } } //+------------------------------------------------------------------+