Here you go ,place it in indicators .Enjoy
#property copyright "Mql5.com forum thread >>" #property link "https://www.mql5.com/en/forum/350019" #property description "Telegram : https://t.me/lorentzor\nInstagram : @rlorentzo\nTwitter : @lorentzo_r\nLinkedIn : https://www.linkedin.com/in/lorentzor\nYoutube : https://www.youtube.com/channel/UCM0Lj06cAJagFWvSpb9N5zA\nFacebook : @LorentzoR" /* ways to connect .> : Telegram : https://t.me/lorentzor Instagram : https://www.instagram.com/rlorentzo /OR/ @rlorentzo Twitter : https://twitter.com/lorentzo_r /OR/ @lorentzo_r LinkedIn : https://www.linkedin.com/in/lorentzor Youtube : https://www.youtube.com/channel/UCM0Lj06cAJagFWvSpb9N5zA Facebook : https://www.facebook.com/LorentzoR /OR/ @LorentzoR Mql5.com : https://www.mql5.com/en/users/lorio */ #property version "1.00" #property strict #property indicator_chart_window input bool AnchorStep=true;//Have Tag Anchor Step ? input bool CommentGuides=true;//Comment Guides ? input bool TagTimeframes=true;//Tag Timeframes ? input color LinesColor=clrDodgerBlue;//Lines Color input int LinesWidth=2;//Lines Width input ENUM_LINE_STYLE LinesStyle=STYLE_SOLID;//Lines Style input bool WithTags=true;//With Tags ? input ENUM_ANCHOR_POINT TagAnchor=ANCHOR_RIGHT_LOWER;//Default Tag Anchor input string TagFont="Arial";//Tags font input int TagFontSize=12;//Tags Font Size input color TagColor=clrOrangeRed;//Tags Color input int MouseClickDeflector=400;//Deflector milliseconds input int ButtonPx=20;//Button Position X input int ButtonPy=20;//Button Position Y input int ButtonSx=200;//Button Size X input int ButtonSy=20;//Button Size Y input int ButtonFontSize=10;//Button Font Size input string ButtonFont="Arial";//Button Font input string ButtonText="New Line>";//Button text //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ string SystemTag="mrLines_",LinesTag="FL_"; string state_comment[],tfname=""; int OnInit() { //--- indicator buffers mapping tfname=TFtoString(PeriodToTF(Period())); ArrayResize(state_comment,4,0); state_comment[0]="Position Price <==\nPosition Start\nPosition End"; state_comment[1]="Position Price\nPosition Start <==\nPosition End"; state_comment[2]="Position Price\nPosition Start\nPosition End <=="; if(AnchorStep){for(int i=0;i<3;i++){state_comment[i]+="\nAlign Tag";}} state_comment[3]="Position Price\nPosition Start\nPosition End\nAlign Tag <=="; mrLines.Abort(true); ChartSetInteger(ChartID(),CHART_EVENT_MOUSE_MOVE,true); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ uint ClickMS=0; int Mcx=0,Mcy=0,PreMcx=0,PreMcy=0; string Mcc,PreMcc; void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- //mousemove //just a click bool click_through=false; if(id==CHARTEVENT_CLICK&&mrLines.State!=eol_none){click_through=true;} if(id==CHARTEVENT_MOUSE_MOVE||click_through) { PreMcx=Mcx;PreMcy=Mcy;PreMcc=Mcc; Mcx=(int)lparam;Mcy=(int)dparam;Mcc=sparam; if(click_through){Mcc="1";} if(PreMcc=="0"&&Mcc!="0") { uint now=GetTickCount(); int diff=(int)(now-ClickMS); if(now<ClickMS){diff=(int)(now)+(int)(UINT_MAX-ClickMS);} if(diff<=MouseClickDeflector){Mcc="0";} if(diff>MouseClickDeflector){ClickMS=now;} } //tag positioning if(mrLines.State==eol_anchor) { double pr=0;datetime ti=0;int subw=0; bool get_price=ChartXYToTimePrice(ChartID(),Mcx,Mcy,subw,ti,pr); //if price is accesed if(get_price){mrLines.ChangeTagAnchor(pr,ti);} //if click mouse button 2 - kill if(Mcc=="2"){mrLines.Abort(true);} //if click mouse button 1 - finish if(Mcc=="1"){mrLines.Abort(false);} } //tag positioning ends here //point b positioning if(mrLines.State==eol_pB) { double pr=0;datetime ti=0;int subw=0; bool get_price=ChartXYToTimePrice(ChartID(),Mcx,Mcy,subw,ti,pr); //if price is accesed if(get_price){mrLines.ChangePointB(ti);} //if click mouse button 2 - kill if(Mcc=="2"){mrLines.Abort(true);} //if click mouse button 1 - proceed to anchor positioning if(Mcc=="1") { PreMcc="0"; Mcc="0"; mrLines.DeleteGuide(); if(WithTags&&AnchorStep){mrLines.State=eol_anchor;Comment(state_comment[3]);} if(!WithTags||!AnchorStep){mrLines.Abort(false);} } } //point b positioning ends here //point a positioning if(mrLines.State==eol_pA) { double pr=0;datetime ti=0;int subw=0; bool get_price=ChartXYToTimePrice(ChartID(),Mcx,Mcy,subw,ti,pr); //if price is accesed if(get_price){mrLines.ChangePointA(ti);} //if click mouse button 2 - kill if(Mcc=="2"){mrLines.Abort(true);} //if click mouse button 1 - proceed to point 2 positioning if(Mcc=="1"){mrLines.State=eol_pB;PreMcc="0";Mcc="0";if(CommentGuides){Comment(state_comment[2]);}} } //point a positioning ends here //if moving the price if(mrLines.State==eol_price) { double pr=0;datetime ti=0;int subw=0; bool get_price=ChartXYToTimePrice(ChartID(),Mcx,Mcy,subw,ti,pr); //if price is accesed if(get_price){mrLines.ChangePrice(pr);} //if click mouse button 2 - kill if(Mcc=="2"){mrLines.Abort(true);} //if click mouse button 1 - proceed to point 1 positioning if(Mcc=="1"){mrLines.State=eol_pA;PreMcc="0";Mcc="0";mrLines.BuildGuide(LinesColor);if(CommentGuides){Comment(state_comment[1]);}} } //if moving the price ends here } //mousemove ends here //click on new line if(id==CHARTEVENT_OBJECT_CLICK&&sparam==SystemTag+"_Make_Line") { double pr=0;datetime ti=0;int subw=0; bool get_price=ChartXYToTimePrice(ChartID(),Mcx,Mcy,subw,ti,pr); //if price is accesed if(get_price) { ObjectsDeleteAll(ChartID(),SystemTag); //get mouse scroll state mrLines.ScrollState=(bool)ChartGetInteger(ChartID(),CHART_MOUSE_SCROLL); if(mrLines.ScrollState){ChartSetInteger(ChartID(),CHART_MOUSE_SCROLL,false);} //set to stage 1 price positioning //initial price mrLines.Price=pr; mrLines.State=eol_price; ClickMS=GetTickCount(); PreMcc="0";Mcc="0"; mrLines.LineName=LinesTag+"_"+IntegerToString(TimeLocal()); mrLines.TagAnchored=TagAnchor; mrLines.TagSide=1;//B mrLines.HasTag=WithTags; mrLines.Cid=ChartID(); mrLines.SubW=0; if(CommentGuides){Comment(state_comment[0]);} string tag_text=DoubleToString(pr,Digits()); if(TagTimeframes){tag_text+=" ["+tfname+"]";} CreateHLWT(ChartID(),0,mrLines.LineName,WithTags,TagAnchor,tag_text,true,Time[100],true,Time[1],pr,pr,LinesColor,LinesWidth,LinesStyle,TagColor,TagFontSize,false,false,false,false); } //if price is accessed ends here } //click on new line ends here } //+------------------------------------------------------------------+ enum editor_state{ eol_none=0, eol_price=1,//placing price eol_pA=2,//placing point A eol_pB=3,//placing point B eol_anchor=4//placing Anchor }; struct editor_of_lines { editor_state State; long Cid; int SubW; bool ScrollState,HasTag; string LineName; double Price; datetime PointA,PointB; ENUM_ANCHOR_POINT TagAnchored; int TagSide;//0 point a ,1 point b editor_of_lines(void){State=eol_none;} //NEW PRICE : void ChangePrice(double new_price){ Price=new_price; ObjectSetDouble(Cid,LineName,OBJPROP_PRICE1,new_price); ObjectSetDouble(Cid,LineName,OBJPROP_PRICE2,new_price); if(HasTag){ ObjectSetDouble(Cid,LineName+"_tag",OBJPROP_PRICE,new_price); string tag_text=DoubleToString(Price,Digits()); if(TagTimeframes){tag_text+=" ["+tfname+"]";} ObjectSetString(Cid,LineName+"_tag",OBJPROP_TEXT,tag_text); } } //CHANGE POINT A void ChangePointA(datetime new_point_a){ PointA=new_point_a; ObjectSetInteger(Cid,LineName,OBJPROP_RAY,false); ObjectSetInteger(Cid,LineName,OBJPROP_TIME1,new_point_a); if(HasTag&&TagSide==0){ObjectSetInteger(Cid,LineName+"_tag",OBJPROP_TIME,new_point_a);} ObjectSetInteger(Cid,SystemTag+"_Guide_Arrow",OBJPROP_TIME,new_point_a); ObjectSetInteger(Cid,SystemTag+"_Guide_Line",OBJPROP_TIME,new_point_a); } //CHANGE POINT B void ChangePointB(datetime new_point_b){ PointB=new_point_b; ObjectSetInteger(Cid,LineName,OBJPROP_RAY_RIGHT,false); ObjectSetInteger(Cid,LineName,OBJPROP_TIME2,new_point_b); if(HasTag&&TagSide==1){ObjectSetInteger(Cid,LineName+"_tag",OBJPROP_TIME,new_point_b);} ObjectSetInteger(Cid,SystemTag+"_Guide_Arrow",OBJPROP_TIME,new_point_b); ObjectSetInteger(Cid,SystemTag+"_Guide_Line",OBJPROP_TIME,new_point_b); } //CHANGE ANCHOR void ChangeTagAnchor(double mouseprice,datetime mousetime){ //midtime datetime midtime=(datetime)((PointA+PointB)/2); //find new side if(mousetime<=midtime){TagSide=0;ObjectSetInteger(Cid,LineName+"_tag",OBJPROP_TIME,PointA);} if(mousetime>midtime){TagSide=1;ObjectSetInteger(Cid,LineName+"_tag",OBJPROP_TIME,PointB);} //find new anchor //above price if(mouseprice>Price){ //and left side if(TagSide==0){TagAnchored=ANCHOR_LEFT_LOWER;} //and right side if(TagSide==1){TagAnchored=ANCHOR_RIGHT_LOWER;} } //below price if(mouseprice<=Price){ //and left side if(TagSide==0){TagAnchored=ANCHOR_LEFT_UPPER;} //and right side if(TagSide==1){TagAnchored=ANCHOR_RIGHT_UPPER;} } ObjectSetInteger(Cid,LineName+"_tag",OBJPROP_ANCHOR,TagAnchored); } //build guide void BuildGuide(color guide_color){ bool v_build=ObjectCreate(Cid,SystemTag+"_Guide_Line",OBJ_VLINE,SubW,0,0); if(v_build){ ObjectSetInteger(Cid,SystemTag+"_Guide_Line",OBJPROP_COLOR,guide_color); ObjectSetInteger(Cid,SystemTag+"_Guide_Line",OBJPROP_STYLE,STYLE_DASH); ObjectSetInteger(Cid,SystemTag+"_Guide_Line",OBJPROP_SELECTABLE,false); ObjectSetInteger(Cid,SystemTag+"_Guide_Line",OBJPROP_BACK,false); ObjectSetInteger(Cid,SystemTag+"_Guide_Line",OBJPROP_WIDTH,1); bool a_build=ObjectCreate(Cid,SystemTag+"_Guide_Arrow",OBJ_TEXT,SubW,0,Price); if(a_build){ ObjectSetInteger(Cid,SystemTag+"_Guide_Arrow",OBJPROP_COLOR,guide_color); ObjectSetInteger(Cid,SystemTag+"_Guide_Arrow",OBJPROP_ANCHOR,ANCHOR_CENTER); ObjectSetString(Cid,SystemTag+"_Guide_Arrow",OBJPROP_FONT,"Wingdings"); ObjectSetString(Cid,SystemTag+"_Guide_Arrow",OBJPROP_TEXT,CharToString(162)); ObjectSetInteger(Cid,SystemTag+"_Guide_Arrow",OBJPROP_FONTSIZE,12); } } } //delete guide void DeleteGuide(){ ObjectsDeleteAll(Cid,SystemTag+"_Guide"); } //Abort void Abort(bool kill_line_under_edit){ if(CommentGuides){Comment("");} //delete objects created if(kill_line_under_edit){ObjectsDeleteAll(Cid,LineName);} //reset state State=eol_none; //restore mouse scroll if(ScrollState){ChartSetInteger(Cid,CHART_MOUSE_SCROLL,true);} //create btn DeckUp(); } //Button void DeckUp(){ ObjectsDeleteAll(ChartID(),SystemTag); HS_Create_Btn(ChartID(),0,SystemTag+"_Make_Line",ButtonSx,ButtonSy,ButtonPx,ButtonPy,ButtonFont,ButtonFontSize,clrRoyalBlue,clrDodgerBlue,BORDER_FLAT,clrGoldenrod,ALIGN_CENTER,ButtonText,false,false); } }; editor_of_lines mrLines; //Period to Timeframe ENUM_TIMEFRAMES PeriodToTF(int period) { if(period==1) return(PERIOD_M1); if(period==5) return(PERIOD_M5); if(period==15) return(PERIOD_M15); if(period==30) return(PERIOD_M30); if(period==60) return(PERIOD_H1); if(period==240) return(PERIOD_H4); if(period==1440) return(PERIOD_D1); if(period==10080) return(PERIOD_W1); if(period==43200) return(PERIOD_MN1); return(PERIOD_CURRENT); } //Timeframe To String string TFtoString(ENUM_TIMEFRAMES TF) { string returnio=""; if(TF==PERIOD_M1) returnio="M1"; if(TF==PERIOD_M5) returnio="M5"; if(TF==PERIOD_M15) returnio="M15"; if(TF==PERIOD_M30) returnio="M30"; if(TF==PERIOD_H1) returnio="H1"; if(TF==PERIOD_H4) returnio="H4"; if(TF==PERIOD_D1) returnio="D1"; if(TF==PERIOD_W1) returnio="W1"; if(TF==PERIOD_MN1) returnio="MN1"; return(returnio); } //CREATE HORIZONTAL LINE WITH TAG void CreateHLWT(long cid, int subw, string line_name, bool has_tag, ENUM_ANCHOR_POINT tag_anchor, string tag_text, bool infinite_left, datetime start_time, bool infinite_right, datetime end_time, double start_price, double end_price, color line_color, int line_width, ENUM_LINE_STYLE line_style, color tag_color, int tag_font_size, bool back, bool selectable, bool tag_back, bool tag_selectable) { bool obji=ObjectCreate(cid,line_name,OBJ_TREND,subw,0,start_price,end_time,end_price); ObjectSetInteger(cid,line_name,OBJPROP_BACK,back); ObjectSetInteger(cid,line_name,OBJPROP_SELECTABLE,selectable); ObjectSetInteger(cid,line_name,OBJPROP_COLOR,line_color); ObjectSetInteger(cid,line_name,OBJPROP_STYLE,line_style); ObjectSetInteger(cid,line_name,OBJPROP_WIDTH,line_width); if(!infinite_left) ObjectSetInteger(cid,line_name,OBJPROP_RAY,false); if(infinite_left) ObjectSetInteger(cid,line_name,OBJPROP_RAY,true); if(!infinite_right) ObjectSetInteger(cid,line_name,OBJPROP_RAY_RIGHT,false); if(infinite_right) ObjectSetInteger(cid,line_name,OBJPROP_RAY_RIGHT,true); //if tag if(has_tag) { string objna=line_name+"_tag"; obji=ObjectCreate(cid,objna,OBJ_TEXT,subw,end_time,end_price); ObjectSetInteger(cid,objna,OBJPROP_COLOR,tag_color); ObjectSetInteger(cid,objna,OBJPROP_ANCHOR,tag_anchor); ObjectSetInteger(cid,objna,OBJPROP_FONTSIZE,tag_font_size); ObjectSetInteger(cid,objna,OBJPROP_BACK,tag_back); ObjectSetInteger(cid,objna,OBJPROP_SELECTABLE,tag_selectable); ObjectSetString(cid,objna,OBJPROP_TEXT,tag_text); } //if tag ends here } //CREATE LINE WITH TAG ENDS HERE //CREATE BTN OBJECT void HS_Create_Btn(long cid, int subw, string name, int sx, int sy, int px, int py, string font, int fontsize, color bck_col, color brd_col, ENUM_BORDER_TYPE brd_type, color txt_col, ENUM_ALIGN_MODE align, string text, bool selectable, bool back) { if(!IsTesting()||IsVisualMode()) { bool obji=ObjectCreate(cid,name,OBJ_BUTTON,subw,0,0); if(obji) { ObjectSetString(0,name,OBJPROP_FONT,font); ObjectSetInteger(0,name,OBJPROP_ALIGN,align); ObjectSetInteger(0,name,OBJPROP_FONTSIZE,fontsize); ObjectSetInteger(0,name,OBJPROP_XSIZE,sx); ObjectSetInteger(0,name,OBJPROP_YSIZE,sy); ObjectSetInteger(0,name,OBJPROP_XDISTANCE,px); ObjectSetInteger(0,name,OBJPROP_YDISTANCE,py); ObjectSetInteger(0,name,OBJPROP_BGCOLOR,bck_col); ObjectSetInteger(0,name,OBJPROP_BORDER_COLOR,brd_col); ObjectSetInteger(0,name,OBJPROP_COLOR,txt_col); ObjectSetInteger(0,name,OBJPROP_BORDER_TYPE,brd_type); ObjectSetInteger(0,name,OBJPROP_SELECTABLE,selectable); ObjectSetInteger(0,name,OBJPROP_BACK,back); ObjectSetString(0,name,OBJPROP_TEXT,text); } } } 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(rates_total);}
Dear Lorentzos,
The indicator is exactly what i was looking for.
Thank you so much, you are a star.
Good trading to you.
Regards
Jason
Hi Lorentzos
How do I save the levels, so when i change timeframe the levels do not automatically delete?
Regards
Jason
Hi Lorentzos
How do I save the levels, so when i change timeframe the levels do not automatically delete?
Regards
Jason
Here you go , i altered it to not delete them.
Here you go , i altered it to not delete them.
Hi ! Thanks for this useful indicator. How can I delete those lines ?
Thank you, but is deleted when I change timeframe and not easy to adjust it or edit.
Hi Lorentzos, thanks for the fantastic indicator.
I was wondering if you could add the option of clicking a line to adjust it's length or move it to another level.
Many thanks George
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
Hi All,
I am struggling to find either a standard or custom drawing tool in MT4 version 4.00 build 1280 that will allow me to draw a horizontal line between two chosen points on a chart, and then show the level in the price axis, or next to the drawn line. Today I am drawing the horizontal levels as best I can using the draw trendline function. However, this does not draw horizontally (180 degrees) as standard, so it takes time to correct the unintended angle of my intended flat line, and I thne have to use the cross-hairs to work out the price level, and use the text function to write down the level.
Here is a manual view of what i am looking for:
Please let me know if anyone has seen this drawing tool functionality available.
Thanks for your help in advance.
Regards
Jason