//+------------------------------------------------------------------+ //| ID Lite Info MA.mq4 | //| 2015, Dina Paches | //| https://login.mql5.com/ru/users/dipach | //+------------------------------------------------------------------+ #property copyright "2015, Dina Paches" #property link "https://login.mql5.com/ru/users/dipach" #property version "1.86" #property strict #property indicator_chart_window #property indicator_buffers 2 //+------------------------------------------------------------------+ /*количество значений МА и дельт, показываемых на чарте в ячейках по оси Х (>=2 or <=30):*/ #define ARRAY_SIZE_X (9) #define ARRAY_SIZE_Y (6) //количество строк в таблице по оси Y #define DISTANCE_XY (1)//дистанция между ячейками таблицы #define COUNT_BUFFERS (2)//количество буферов (для Moving Averages) #define LINE_NUMBER "Line: ",__LINE__,", " //+------------------------------------------------------------------+ //| Выбор количества десятичных знаков для значений МА: | //+------------------------------------------------------------------+ enum varDigits { auto=-1,//current chart dig0=0,//0 dig1=1,//1 dig2=2,//2 dig3=3,//3 dig4=4,//4 dig5=5,//5 dig6=6,//6 dig7=7,//7 dig8=8,//8 }; //+------------------------------------------------------------------+ /*показывать расчётные отрезки линий МА на чарте:*/ input bool showLine=true;//Show lines MA /*отступ в пунктах для первой МА:*/ input int indent1=0;//Shift in points from MA1 (-/+ Down or Up) /*отступ в пунктах для второй МА:*/ input int indent2=0;//Shift in points from MA2 (-/+ Down or Up) /*количество десятичных знаков для отображаемых в таблице значений:*/ input varDigits digCh=auto;//Decimal digits /*номер начального бара для МА:*/ input int shift=1;//Shift (bar for first value): sinput string stripe1="+++++++++++++++++++++";//+++++++++++++++++++++ /*период первой МА:*/ input int ma_period1=1;//Period Moving Averages (1)>= 1 or <= 3000: /*выбор метода усреднения для первой МА:*/ input ENUM_MA_METHOD ma_method1=MODE_SMA;//MA method (1): /*выбор типа цены для первой МА:*/ input ENUM_APPLIED_PRICE applied_price1=PRICE_HIGH;//Apply to (1): sinput string stripe2="+++++++++++++++++++++";//+++++++++++++++++++++ /*период второй МА:*/ input int ma_period2=1;//Period Moving Averages (2)>= 1 or <= 3000: /*выбор метода усреднения для второй МА:*/ input ENUM_MA_METHOD ma_method2=MODE_SMA;//MA method (2): /*выбор типа цены для второй МА:*/ input ENUM_APPLIED_PRICE applied_price2=PRICE_LOW;//Apply to (2): sinput string stripe3="+++++++++++++++++++++";//+++++++++++++++++++++ /*дистанция таблицы от правого края графика:*/ input int xDistance=3;//X coordinate /*дистанция таблицы от верхнего края графика:*/ input int yDistance=3;//Y coordinate /*цвет основного фона и цвет фона ячеек таблицы, если значение МА равно предыдущему:*/ input color backClrMain=C'224,224,224';// background color (table and Equal) /*цвет фона ячейки таблицы, если значение МА выше предыдущего:*/ input color backClrUp=clrCornflowerBlue;//background color (Up) /*цвет фона ячейки таблицы, если значение МА ниже предыдущего:*/ input color backClrDown=C'255,85,85';//background color (Down) /*цвет шрифта для значений МА:*/ input color textClrMA=C'48,48,48';//text color for MA /*цвет шрифта для значений дельты, если значение МА равно предыдущему:*/ input color textClrDelta=clrDimGray;// color text for delta /*ширина ячеек таблицы по оси Х:*/ input int widthObj=60;//width /*высота ячеек для значений МА в таблице по оси Y:*/ input int heightObj=18;//height /*размер шрифта для значений МА:*/ input int fontSize=9;//font size /*объекты индикатора на заднем плане чарта*/ input bool backObj=true;//in the background //+------------------------------------------------------------------+ double priceM1buffer[],priceM2buffer[],indentK1,indentK2,pointK; int dig,minBars,shiftK,switchButtonClick,chartWidthK,switchMA1,switchMA2, coordinateY0,coordinateY1,coordinateX0,coordinateX1; color backClrObjOddY[COUNT_BUFFERS+1][ARRAY_SIZE_X], textClrObjEvenY[COUNT_BUFFERS][ARRAY_SIZE_X]; string prefixObj,symb, nameObj[ARRAY_SIZE_Y][ARRAY_SIZE_X], textObjOddY[COUNT_BUFFERS+1][ARRAY_SIZE_X], textObjEvenY[COUNT_BUFFERS][ARRAY_SIZE_X], nameObjBut0,nameObjBut1; bool changeClr0[ARRAY_SIZE_X],changeClr1[ARRAY_SIZE_X]; ENUM_TIMEFRAMES timeframe1; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { symb=Symbol(); prefixObj=StringConcatenate("vMA(",IntegerToString(COUNT_BUFFERS), "):",symb,"_",xDistance,yDistance); IndicatorSetString(INDICATOR_SHORTNAME,prefixObj); //+------------------------------------------------------------------+ if(!SetOnInitAny())return(INIT_FAILED); //+------------------------------------------------------------------+ SetOnInitTable(); //+------------------------------------------------------------------+ /*установка значений буферов индикатора:*/ SetIndexBuffer(0,priceM1buffer,INDICATOR_DATA); SetIndexBuffer(1,priceM2buffer,INDICATOR_DATA); if(showLine==true)//если показывать на чарте линиями расчётные участки МА { for(int i=0;i0) { ChangeValuesTable0(1,priceM1buffer,0,newValues,changeClr0,clrK1); ChangeValuesTable0(3,priceM2buffer,1,newValues,changeClr1,clrK2); ChangeValuesTable1(5,priceM1buffer,priceM2buffer,2,newValues); } /*+------------------------------------------------------------------+*/ } }// if(timeNewBar!=time[0]) //+------------------------------------------------------------------+ return(rates_total); }//int OnCalculate //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //+------------------------------------------------------------------+ //| Событие щелчка мыши на графическом объекте | //+------------------------------------------------------------------+ if(id==CHARTEVENT_OBJECT_CLICK) { /*+------------------------------------------------------------------+ если клик мыши произведён в пределах координат имеющейся сейчас на чарте кнопки индикатора:*/ if(lparam>=coordinateX0 && lparam<=coordinateX1 && dparam>=coordinateY0 && dparam<=coordinateY1) { string clickedChartObject=sparam; /*и если это клик по кнопке в виде полосы под заголовком таблицы:*/ if(StringCompare(clickedChartObject,nameObjBut0,true)==0) { bool stateBut=ObjectGetInteger(0,clickedChartObject,OBJPROP_STATE); /*и если при этом клике кнопка нажата:*/ if(stateBut==true) { /*то удаление таблицы для того, чтобы в то время, пока она "свёрнута", не было случайных удалений с чарта её каких-либо объектов (программно или вручную через "Список объектов"):*/ ObjectsDeleteAll(0,prefixObj,0,EMPTY); /*значение флага, что если в дальнейшем ширина чарта будет изменяться, то пересчёт границы кликов по кнопке "свёрнутой" таблицы:*/ switchButtonClick=3; /*создание на чарте кнопки "свёрнутой" таблицы:*/ SetButtonMin(switchButtonClick,nameObjBut1,xDistance+heightObj, yDistance,heightObj,heightObj); ChartRedraw(); return; }//if(stateBut==true) }//if(StringCompare(clickedChartObject,nameObjBut0,true)==0) /*+------------------------------------------------------------------+ иначе, если это клик по кнопке "свёрнутой" таблицы:*/ else if(StringCompare(clickedChartObject,nameObjBut1,true)==0) { bool stateBut=ObjectGetInteger(0,clickedChartObject,OBJPROP_STATE); if(stateBut==true) { ObjDelete(0,nameObjBut1);//удаление кнопки "свёрнутой" таблицы TableCreate();//отображение таблицы на чарте ChartRedraw(); return; } }//if(StringCompare(clickedChartObject,nameObjBut1,true)==0) else return; }//lparam/dparam else return; }// if(id==CHARTEVENT_OBJECT_CLICK) //+------------------------------------------------------------------+ //| Изменение размеров графика или изменение свойств графика через | //| диалог свойств | //+------------------------------------------------------------------+ else if(id==CHARTEVENT_CHART_CHANGE) { int ch=ChartWidthInPixels(); /*если изменилась ширина графика, то пересчёт координат кнопок минимизации:*/ if(chartWidthK!=ch) { chartWidthK=ch; switch(switchButtonClick) { case 1:GetClickCoordinateObj(nameObjBut0); break; case 3:GetClickCoordinateObj(nameObjBut1);break; default: break; } return; } else return; } return; } //+------------------------------------------------------------------+ //| Установка и ограничения различных параметров в OnInit: | //+------------------------------------------------------------------+ bool SetOnInitAny() { /*+------------------------------------------------------------------+ если число строк по оси X < или > ограничения:*/ if(ARRAY_SIZE_X<2 || ARRAY_SIZE_X>30) { Print(LINE_NUMBER,"Error code: ARRAY_SIZE_X."); return(false); } /*+------------------------------------------------------------------+ Этот индикатор не будет удалять свои объекты на чарте, если билд торгового терминала меньше 840, поскольку в нём есть функция, ставшая доступной с 840-го билда. Поэтому при запуске программы - проверка на номер билда торгового терминала:*/ if(TerminalInfoInteger(TERMINAL_BUILD)<840) { Alert("Indicator removed. The client terminal build number < 840."); return(false); } //+------------------------------------------------------------------+ /*проверки на корректность периодов для МА:*/ if(!CheckInput(ma_period1,"Period Moving Averages (1)"))return(false); if(!CheckInput(ma_period2,"Period Moving Averages (2)"))return(false); /*+------------------------------------------------------------------+ если задан начальный бар <1, то начальный бар = 1:*/ shiftK=(shift<1)?1:shiftK=shift; //+------------------------------------------------------------------+ timeframe1=PERIOD_CURRENT; /*две строки ниже применимы только для значений МА с текущего таймфрейма и символа:*/ int minP1=ma_period1+ARRAY_SIZE_X+shiftK+5; int minP2=ma_period2+ARRAY_SIZE_X+shiftK+5; /*минимальное количество баров на чарте, при котором индикатор будет работать:*/ minBars=MathMax(minP1,minP2); //+------------------------------------------------------------------+ /*установка переключателям значений применять или не применять функцию iMA при работе индикатора:*/ switchMA1=-1;switchMA2=-1; SetOnInitSwitchMA(switchMA1,ma_period1,ma_method1,applied_price1); SetOnInitSwitchMA(switchMA2,ma_period2,ma_method2,applied_price2); //+------------------------------------------------------------------+ dig=(digCh==auto)?Digits():digCh;//количество десятичных знаков /*+------------------------------------------------------------------+ для преобразования дельты из десятичных знаков в вид целого числа:*/ pointK=MathPow(10,dig); /*+------------------------------------------------------------------+ если не задан отступ от МА или он больше/меньше ограничения, то отступ равен 0:*/ SetInputIndent(indent1,indentK1); SetInputIndent(indent2,indentK2); //--- return(true); } //+------------------------------------------------------------------+ //|Функция установки значений переключателя, для определения | //|применять или не применять функцию iMA в основном коде: | //+------------------------------------------------------------------+ int SetOnInitSwitchMA(int &switch_MA, const int ma_period, const ENUM_MA_METHOD ma_method, const ENUM_APPLIED_PRICE applied_price) { if(ma_period==1 && ma_method==MODE_SMA && (applied_price==PRICE_CLOSE || applied_price==PRICE_OPEN ||applied_price==PRICE_HIGH || applied_price==PRICE_LOW)) { /*если в свойствах выбрана МА, как простая скользящая средняя с периодом 1 то считать по отметкам баров, не применяя iMA:*/ switch_MA=0; } else {switch_MA=1;}//иначе, применять iMA //--- return(switch_MA); } //+------------------------------------------------------------------+ //| Функция для формирования значений таблицы в OnInit: | //+------------------------------------------------------------------+ void SetOnInitTable() { //+------------------------------------------------------------------+ switchButtonClick=-1;chartWidthK=-1; /*+------------------------------------------------------------------+ цвет фона ячеек таблицы со значениями МА и дельт между самими МА при инициализации индикатора*/ for(int y=0;y-1){ObjectDelete(chart_ID,name);} //--- return(true); } //+------------------------------------------------------------------+ //|Функция установки таблицы индикатора: | //| | //| | //+------------------------------------------------------------------+ void TableCreate() { string toolTipM1=NULL,toolTipM2=NULL,toolTip="Number of bar"; int xDis=widthObj+DISTANCE_XY, /*высота ячеек для заголовка таблицы и значений дельт поменьше, чем для отметок МА:*/ heightObjMin=(heightObj/3)*2, /*шрифт для заголовка таблицы и значений дельт между соседними последовательными значениями каждой из МА, поменьше, чем для значений МА и дельт между самими МА:*/ font=fontSize-1; //+------------------------------------------------------------------+ //|Заголовок таблицы: | //+------------------------------------------------------------------+ for(int x=0;x 3000."); Alert(t); return(false); } return(true); } //+------------------------------------------------------------------+ //|Функция преобразует и задаёт отступ из числа int в вид числа | //|double: | //+------------------------------------------------------------------+ double SetInputIndent(const int indent,//отступ в пунктах, заданный во внешних параметрах double &indentK)//наименование переменной, применяемой в коде для отступов { int p=(int)(100*pointK);//максимальное значение отступа в пунктах int ind0=(int)MathAbs(indent); /*+------------------------------------------------------------------+ если не задан отступ вверх или вниз от МА или он больше/меньше ограничения, то отступ равен 0:*/ indentK=(ind0==0 || ind0>=p)?0.0:indent*Point(); //+------------------------------------------------------------------+ return(indentK); } //+------------------------------------------------------------------+ //| Функция задаёт имена объектам двумерного массива | //+------------------------------------------------------------------+ void NameObjTwoDArray(int countY,//сколько строк по оси Y string &array[][ARRAY_SIZE_X],//массив для имён объектов string dt="_")//мини-префикс) { string text=NULL; for(int y=0;y