//+------------------------------------------------------------------+ //| iJenkins_V1.01.mq4 | //| Copyright 2017, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2017, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.01" #property strict #property indicator_chart_window sinput string _Text_02 = "-----Layout settings"; // layout settings sinput string objectPreamble = "iJ_1_"; // unique object identifier sinput int xAnchor = 1200; // X anchor for panel sinput int yAnchor = 20; // Y anchor for panel sinput color panelBgColor = clrLightGray; // Panel background color sinput color panelBorderColor = clrWhiteSmoke; // Panel border color sinput int panelBorderWidth = 2; // Panel border width sinput int btnWidth = 45; // Button width sinput int btnHeight = 25; // Button height sinput int btnTextSize = 8; // Button font size sinput int btnSpacing = 5; // Button spacing sinput color textColor = clrBlack; // Text color sinput color clrTrendline = clrYellow; // Color reference line sinput int widthTrendline = 1; // Width reference line sinput ENUM_LINE_STYLE lineStyleTrend = STYLE_DOT; // Line style trend line sinput color clrGrid = clrYellow; // Color 1 grid fibo sinput color clrGrid_2 = clrAqua; // Color 2 grid fibo extensions sinput int widthGridline = 1; // Width grid lines sinput ENUM_LINE_STYLE lineStyleGrid = STYLE_DOT; // Line style grid string trendLineAngle_01 = objectPreamble + "Trend_Angle_01"; int panelWidth = 200; int panelHeight = 300; bool editActive, calculateActive; double angle_1, price_1, price_2; long chartID = 0; datetime final_time_1; datetime final_time_2; double final_price_1; double final_price_2; double angle; double chartPriceMin; double chartPriceMax; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping deleteObjects(); createPanel(); editActive = false; calculateActive = false; chartID = ChartID(); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { // delete objects deleteObjects(); return( 0 ); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| Timer function | //+------------------------------------------------------------------+ void OnTimer() { //--- } //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- if (id == CHARTEVENT_OBJECT_CLICK) { if (StringFind(sparam, objectPreamble + "btnConfigure") >= 0) { configure(); } if (StringFind(sparam, objectPreamble + "btnDraw") >= 0) { calculate(); } if (StringFind(sparam, objectPreamble + "btnDelete") >= 0) { deleteGrid(); } } } //+------------------------------------------------------------------+ void createPanel() { int yOffset; panelWidth = 2 * btnWidth + 3 * btnSpacing; panelHeight = 2 * btnHeight + 3 * btnSpacing; SetPanel(objectPreamble+"Panel", 0, xAnchor, yAnchor, panelWidth, panelHeight, panelBgColor, panelBorderColor, panelBorderWidth); Create_Button(objectPreamble +"btnConfigure","Conf.", 0, btnWidth, btnHeight, xAnchor + btnSpacing, yAnchor + btnSpacing, clrGreen, textColor, panelBorderColor, btnTextSize); Create_Button(objectPreamble +"btnDraw","Draw", 0, btnWidth, btnHeight, xAnchor + 2*btnSpacing + btnWidth, yAnchor + btnSpacing, clrRed, textColor, panelBorderColor, btnTextSize); yOffset = yAnchor + btnHeight + 2*btnSpacing; Create_Button(objectPreamble +"btnDelete","Delete grid", 0, 2*btnWidth + btnSpacing, btnHeight, xAnchor + btnSpacing, yOffset, clrRed, textColor, panelBorderColor, btnTextSize); } //+------------------------------------------------------------------+ void deleteObjects() { ObjectsDeleteAll(); string s; string name; s = objectPreamble; for (int i = ObjectsTotal() - 1; i >= 0; i--) { name = ObjectName(i); if (StringSubstr(name, 0, StringLen(s)) == s) { ObjectDelete(name); } } } void Create_Button(string but_name, string label, int window, int xsize, int ysize, int xdist, int ydist, int bgcolor, int fcolor, int bcolor, int _fontSize) { if(ObjectFind(0,but_name)<0) { if(!ObjectCreate(0,but_name,OBJ_BUTTON, window,0,0)) { Print(__FUNCTION__, ": failed to create the button! Error code = ",GetLastError()); return; } ObjectSetString(0,but_name,OBJPROP_TEXT,label); ObjectSetInteger(0,but_name,OBJPROP_XSIZE,xsize); ObjectSetInteger(0,but_name,OBJPROP_YSIZE,ysize); ObjectSetInteger(0,but_name,OBJPROP_CORNER,CORNER_LEFT_UPPER); ObjectSetInteger(0,but_name,OBJPROP_XDISTANCE,xdist); ObjectSetInteger(0,but_name,OBJPROP_YDISTANCE,ydist); ObjectSetInteger(0,but_name,OBJPROP_BGCOLOR,bgcolor); ObjectSetInteger(0,but_name,OBJPROP_COLOR,fcolor); ObjectSetInteger(0,but_name,OBJPROP_BORDER_COLOR,bcolor); ObjectSetInteger(0,but_name,OBJPROP_FONTSIZE,_fontSize); ObjectSetInteger(0,but_name,OBJPROP_HIDDEN,true); ObjectSetInteger(0,but_name, OBJPROP_CORNER,5); //ObjectSetInteger(0,but_name,OBJPROP_BORDER_COLOR,ChartGetInteger(0,CHART_COLOR_FOREGROUND)); ObjectSetInteger(0,but_name,OBJPROP_BORDER_TYPE,BORDER_FLAT); ChartRedraw(); } } //+------------------------------------------------------------------+ void SetText(string name,string text, int window, int x,int y,color colour, int _fontSize=12) { if (ObjectFind(0,name)<0) ObjectCreate(0,name,OBJ_LABEL,window,0,0); ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x); ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y); ObjectSetInteger(0,name,OBJPROP_COLOR,colour); ObjectSetInteger(0,name,OBJPROP_FONTSIZE,_fontSize); ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_LEFT_UPPER); ObjectSetString(0,name,OBJPROP_TEXT,text); } //+------------------------------------------------------------------+ void SetObjText(string name, string CharToStr,int x,int y,color colour,int fontsize) { if(ObjectFind(0,name)<0) ObjectCreate(0,name,OBJ_LABEL,0,0,0); ObjectSetInteger(0,name,OBJPROP_FONTSIZE,fontsize); ObjectSetInteger(0,name,OBJPROP_COLOR,colour); ObjectSetInteger(0,name,OBJPROP_BACK,false); ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x); ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y); ObjectSetString(0,name,OBJPROP_TEXT,CharToStr); ObjectSetString(0,name,OBJPROP_FONT,"Wingdings"); //Alert("Hier"); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void SetPanel(string name,int sub_window,int x, int y, int width, int height, color bg_color, color border_clr,int border_width) { if(ObjectCreate(0,name,OBJ_RECTANGLE_LABEL,sub_window,0,0)) { ObjectSetInteger(0,name,OBJPROP_XDISTANCE,x); ObjectSetInteger(0,name,OBJPROP_YDISTANCE,y); ObjectSetInteger(0,name,OBJPROP_XSIZE,width); ObjectSetInteger(0,name,OBJPROP_YSIZE,height); ObjectSetInteger(0,name,OBJPROP_COLOR,border_clr); ObjectSetInteger(0,name,OBJPROP_BORDER_TYPE,BORDER_FLAT); ObjectSetInteger(0,name,OBJPROP_WIDTH,border_width); ObjectSetInteger(0,name,OBJPROP_CORNER,CORNER_LEFT_UPPER); ObjectSetInteger(0,name,OBJPROP_STYLE,STYLE_SOLID); ObjectSetInteger(0,name,OBJPROP_BACK,true); ObjectSetInteger(0,name,OBJPROP_SELECTABLE,0); ObjectSetInteger(0,name,OBJPROP_SELECTED,0); ObjectSetInteger(0,name,OBJPROP_HIDDEN,true); ObjectSetInteger(0,name,OBJPROP_ZORDER,0); ObjectSetInteger(0,name, OBJPROP_CORNER,5); } ObjectSetInteger(0,name,OBJPROP_BGCOLOR,bg_color); } //+------------------------------------------------------------------+ //| Create a trend line by angle | //+------------------------------------------------------------------+ bool TrendByAngleCreate(const long chart_ID=0, // chart's ID const string name="TrendLine", // line name const int sub_window=0, // subwindow index datetime time=0, // point time double price=0, // point price datetime time_2=0, // point time double price_2=0, // point price const double angle=45.0, // slope angle const color clr=clrRed, // line color const ENUM_LINE_STYLE style=STYLE_SOLID, // line style const int width=1, // line width const bool back=false, // in the background const bool selection=true, // highlight to move const bool ray_right=true, // line's continuation to the right const bool hidden=true, // hidden in the object list const long z_order=0) // priority for mouse click { //--- create the second point to facilitate dragging the trend line by mouse //datetime time2=0; //double price2=0; //--- set anchor points' coordinates if they are not set //ChangeTrendEmptyPoints(time,price,time2,price2); //--- reset the error value ResetLastError(); //--- create a trend line using 2 points if(!ObjectCreate(chart_ID,name,OBJ_TRENDBYANGLE,sub_window,time,price,time_2,price_2)) { Print(__FUNCTION__, ": failed to create a trend line! Error code = ",GetLastError()); return(false); } //--- change trend line's slope angle; when changing the angle, coordinates of the second //--- point of the line are redefined automatically according to the angle's new value ObjectSetDouble(chart_ID,name,OBJPROP_ANGLE,angle); //--- set line color ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr); //--- set line style ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style); //--- set line width ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width); //--- display in the foreground (false) or background (true) ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back); //--- enable (true) or disable (false) the mode of moving the line by mouse //--- when creating a graphical object using ObjectCreate function, the object cannot be //--- highlighted and moved by default. Inside this method, selection parameter //--- is true by default making it possible to highlight and move the object ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection); //--- enable (true) or disable (false) the mode of continuation of the line's display to the right ObjectSetInteger(chart_ID,name,OBJPROP_RAY_RIGHT,ray_right); //--- hide (true) or display (false) graphical object name in the object list ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden); //--- set the priority for receiving the event of a mouse click in the chart ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order); //--- successful execution return(true); } //+------------------------------------------------------------------+ //| Check the values of trend line's anchor points and set default | //| values for empty ones | //+------------------------------------------------------------------+ void ChangeTrendEmptyPoints(datetime &time1,double &price1, datetime &time2,double &price2) { //--- if the first point's time is not set, it will be on the current bar if(!time1) time1=TimeCurrent(); //--- if the first point's price is not set, it will have Bid value if(!price1) price1=SymbolInfoDouble(Symbol(),SYMBOL_BID); //--- set coordinates of the second, auxiliary point //--- the second point will be 9 bars left and have the same price datetime second_point_time[10]; CopyTime(Symbol(),Period(),time1,10,second_point_time); time2=second_point_time[0]; price2=price1; } void configure() { bool OK; long nbrOfBarsVisible, nbrOfBarsInChart, firstVisibleBar; datetime time_1, time_2; double price_1, price_2; if (editActive) { return; } editActive = true; calculateActive = false; ObjectSetInteger(0,objectPreamble +"btnConfigure",OBJPROP_BGCOLOR, clrRed); ObjectSetInteger(0,objectPreamble +"btnDraw",OBJPROP_BGCOLOR, clrGreen); ChartSetInteger(chartID, CHART_SCALEFIX, 0, 0); ChartRedraw(chartID); // check for existance of angle trendline if (ObjectFind(chartID, trendLineAngle_01) >= 0) { // show line ObjectSetInteger(chartID, trendLineAngle_01, OBJPROP_SELECTABLE, 1); ObjectSetInteger(chartID, trendLineAngle_01, OBJPROP_SELECTED, 1); } else { OK = ChartGetDouble(chartID, CHART_PRICE_MIN, 0, chartPriceMin); OK = ChartGetDouble(chartID, CHART_PRICE_MAX, 0, chartPriceMax); OK = ChartGetInteger(chartID, CHART_VISIBLE_BARS, 0, nbrOfBarsVisible); OK = ChartGetInteger(chartID, CHART_WIDTH_IN_BARS, 0, nbrOfBarsInChart); OK = ChartGetInteger(chartID, CHART_FIRST_VISIBLE_BAR, 0, firstVisibleBar); if (nbrOfBarsVisible < nbrOfBarsInChart) { time_1 = iTime(Symbol(), PERIOD_CURRENT, int(nbrOfBarsVisible/2)); time_2 = iTime(Symbol(), PERIOD_CURRENT, int(nbrOfBarsVisible/4)); price_1 = chartPriceMin + (chartPriceMax - chartPriceMin) / 3; price_2 = price_1 + (chartPriceMax - chartPriceMin) / 3; TrendByAngleCreate(chartID, trendLineAngle_01, 0, time_1, price_1, time_2, price_2, 45.0, clrTrendline, lineStyleTrend, widthTrendline, false, true, false, false, 0); } else { time_1 = iTime(Symbol(), PERIOD_CURRENT, int(firstVisibleBar - nbrOfBarsVisible/4)); time_2 = iTime(Symbol(), PERIOD_CURRENT, int(firstVisibleBar - nbrOfBarsVisible/2)); price_1 = chartPriceMin + (chartPriceMax - chartPriceMin) / 3; price_2 = price_1 + (chartPriceMax - chartPriceMin) / 3; TrendByAngleCreate(chartID, trendLineAngle_01, 0, time_1, price_1, time_2, price_2, 45.0, clrTrendline, lineStyleTrend, widthTrendline, false, true, false, false, 0); } } ObjectSetInteger(0,objectPreamble +"btnConfigure",OBJPROP_STATE, 0); } void calculate() { if (calculateActive) { return; } if (ObjectFind(chartID, trendLineAngle_01) < 0) { Alert("No angle line drawn!!"); editActive = false; calculateActive = false; ObjectSetInteger(0,objectPreamble +"btnDraw",OBJPROP_STATE, 0); ObjectSetInteger(0,objectPreamble +"btnConfigure",OBJPROP_BGCOLOR, clrGreen); ObjectSetInteger(0,objectPreamble +"btnDraw",OBJPROP_BGCOLOR, clrRed); return; } editActive = false; calculateActive = true; ChartSetInteger(chartID, CHART_SCALEFIX, 0, 1); ChartRedraw(chartID); ObjectSetInteger(0,objectPreamble +"btnConfigure",OBJPROP_BGCOLOR, clrGreen); ObjectSetInteger(0,objectPreamble +"btnDraw",OBJPROP_BGCOLOR, clrRed); ObjectSetInteger(chartID, trendLineAngle_01, OBJPROP_SELECTABLE, 0); ObjectSetInteger(chartID, trendLineAngle_01, OBJPROP_SELECTED, 0); // get the info's from the trend line final_time_1 = ObjectGetInteger(chartID, trendLineAngle_01, OBJPROP_TIME, 0); final_time_2 = ObjectGetInteger(chartID, trendLineAngle_01, OBJPROP_TIME2, 0); final_price_1 = ObjectGetDouble(chartID, trendLineAngle_01, OBJPROP_PRICE, 0); final_price_2 = ObjectGetDouble(chartID, trendLineAngle_01, OBJPROP_PRICE2, 0); angle = ObjectGetDouble(chartID, trendLineAngle_01, OBJPROP_ANGLE, 0); drawFibos(final_price_1, final_price_2); drawCycles(); ObjectSetInteger(0,objectPreamble +"btnCalculate",OBJPROP_STATE, 0); } void drawFibos(double price_1, double price_2) { double delta = (price_2 - price_1) / 8.0; string name; double price; color tmpColor; // delete existing fiboe lines string s = objectPreamble + "_fibo"; for (int i = ObjectsTotal() - 1; i >= 0; i--) { name = ObjectName(i); if (StringSubstr(name, 0, StringLen(s)) == s) { ObjectDelete(name); } } // draw fibo line + addionals for (int u = 0; u < 17; u++) { price = price_1 - 4 * delta + u * delta; //Alert(price); if (u > 3 && u < 13) { tmpColor = clrGrid; } else { tmpColor = clrGrid_2; } HLineCreate(chartID, objectPreamble + "_fibo" + IntegerToString(u), 0, price, tmpColor, lineStyleGrid, widthGridline, false, false, true, 0); } } void drawCycles() { // calculate the leg length double pi = 3.1415926; double legLength_a1, legLength_a2, delta; string strCycle = objectPreamble + "_cycle"; delta = final_price_2-final_price_1; legLength_a1 = (delta * MathSin((90.0-angle)*pi/180.0)) / MathSin(angle*pi/180.0); legLength_a2 = (delta * MathSin(45.0*pi/180.0)) / MathSin(45.0*pi/180.0); int time = (legLength_a2/legLength_a1) * (final_time_2 - final_time_1); // delete cycle ObjectDelete(chartID, strCycle); // set the cycles datetime secondTime = final_time_1 + time/8; CyclesCreate(chartID, strCycle, 0, final_time_1, final_price_1, secondTime, final_price_1, clrGrid, lineStyleGrid, widthGridline, false, false, true, 0); } void deleteGrid() { // delete fibo's string s = objectPreamble + "_fibo"; string name; for (int i = ObjectsTotal() - 1; i >= 0; i--) { name = ObjectName(i); if (StringSubstr(name, 0, StringLen(s)) == s) { ObjectDelete(name); } } // delete cycles and trendline ObjectDelete(chartID, objectPreamble + "_cycle"); ObjectDelete(chartID, trendLineAngle_01); editActive = false; calculateActive = false; ObjectSetInteger(0,objectPreamble +"btnConfigure",OBJPROP_BGCOLOR, clrGreen); ObjectSetInteger(0,objectPreamble +"btnDraw",OBJPROP_BGCOLOR, clrRed); ObjectSetInteger(0,objectPreamble +"btnDelete",OBJPROP_STATE, 0); } //+------------------------------------------------------------------+ //| Create the horizontal line | //+------------------------------------------------------------------+ bool HLineCreate(const long chart_ID=0, // chart's ID const string name="HLine", // line name const int sub_window=0, // subwindow index double price=0, // line price const color clr=clrRed, // line color const ENUM_LINE_STYLE style=STYLE_SOLID, // line style const int width=1, // line width const bool back=false, // in the background const bool selection=true, // highlight to move const bool hidden=true, // hidden in the object list const long z_order=0) // priority for mouse click { //--- if the price is not set, set it at the current Bid price level if(!price) price=SymbolInfoDouble(Symbol(),SYMBOL_BID); //--- reset the error value ResetLastError(); //--- create a horizontal line if(!ObjectCreate(chart_ID,name,OBJ_HLINE,sub_window,0,price)) { Print(__FUNCTION__, ": failed to create a horizontal line! Error code = ",GetLastError()); return(false); } //--- set line color ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr); //--- set line display style ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style); //--- set line width ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width); //--- display in the foreground (false) or background (true) ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back); //--- enable (true) or disable (false) the mode of moving the line by mouse //--- when creating a graphical object using ObjectCreate function, the object cannot be //--- highlighted and moved by default. Inside this method, selection parameter //--- is true by default making it possible to highlight and move the object ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection); //--- hide (true) or display (false) graphical object name in the object list ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden); //--- set the priority for receiving the event of a mouse click in the chart ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order); //--- successful execution return(true); } //+------------------------------------------------------------------+ //| Create cycle lines | //+------------------------------------------------------------------+ bool CyclesCreate(const long chart_ID=0, // chart's ID const string name="Cycles", // object name const int sub_window=0, // subwindow index datetime time1=0, // first point time double price1=0, // first point price datetime time2=0, // second point time double price2=0, // second point price const color clr=clrRed, // color of cycle lines const ENUM_LINE_STYLE style=STYLE_SOLID, // style of cycle lines const int width=1, // width of cycle lines const bool back=false, // in the background const bool selection=true, // highlight to move const bool hidden=true, // hidden in the object list const long z_order=0) // priority for mouse click { //--- set anchor points' coordinates if they are not set //ChangeCyclesEmptyPoints(time1,price1,time2,price2); //--- reset the error value ResetLastError(); //--- create cycle lines by the given coordinates if(!ObjectCreate(chart_ID,name,OBJ_CYCLES,sub_window,time1,price1,time2,price2)) { Print(__FUNCTION__, ": failed to create cycle lines! Error code = ",GetLastError()); return(false); } //--- set color of the lines ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr); //--- set display style of the lines ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style); //--- set width of the lines ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width); //--- display in the foreground (false) or background (true) ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back); //--- enable (true) or disable (false) the mode of moving the lines by mouse //--- when creating a graphical object using ObjectCreate function, the object cannot be //--- highlighted and moved by default. Inside this method, selection parameter //--- is true by default making it possible to highlight and move the object ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection); ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection); //--- hide (true) or display (false) graphical object name in the object list ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden); //--- set the priority for receiving the event of a mouse click in the chart ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order); //--- successful execution return(true); }