//+------------------------------------------------------------------+ //| Pivot.mq4 | //| | //| | //+------------------------------------------------------------------+ #property copyright "Copyright Shimodax" #property link "http://www.strategybuilderfx.com" #property indicator_chart_window // ---- user input --------------- /* LocalTimeZone: TimeZone for which MT4 shows your local time, e.g. 1 or 2 for Europe (GMT+1 or GMT+2 (daylight savings time). Use zero for no adjustment. DestTimeZone: TimeZone for the session from which to calculate the levels (e.g. 1 or 2 for the European session (without or with daylight savings time). Use zero for GMT Example: If your MT server is living in the EST (Eastern Standard Time, GMT-5) zone and want to calculate the levels for the London trading session (European time in summer GMT+1), then enter -5 for LocalTimeZone, 1 for Dest TimeZone. Please understand that the LocalTimeZone setting depends on the time on your MetaTrader charts (for example the demo server from MetaQuotes always lives in CDT (+2) or CET (+1), no matter what the clock on your wall says. If in doubt, leave everything to zero. */ extern int LocalTimeZone= 0; extern int DestTimeZone= 0; extern int LineStyle= 2; extern bool ShowComment = true; extern bool ShowLevelPrices = false; extern bool ShowHighLowOpen = true; extern bool ShowSweetSpots = true; extern bool ShowPivots = true; extern bool ShowFibos= false; extern bool ShowMidPitvot = false; extern bool ShowCamarilla = false; extern int BarForLabels= 10; // number of bars from right, where lines labels will be shown extern bool DebugLogger = false; /* The following doesn't work yet, please leave it to 0/24: TradingHoursFrom: First hour of the trading session in the destination time zone. TradingHoursTo: Last hour of the trading session in the destination time zone (the hour starting with this value is excluded, i.e. 18 means up to 17:59 o'clock) Example: If you are lving in the EST (Eastern Standard Time, GMT-5) zone and want to calculate the levels for the London trading session (European time GMT+1, 08:00 - 17:00), then enter -5 for LocalTimeZone, 1 for Dest TimeZone, 8 for HourFrom and 17 for hour to. */ int TradingHoursFrom= 0; int TradingHoursTo= 24; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { return(0); } int deinit() { int obj_total= ObjectsTotal(); for (int i= obj_total; i>=0; i--) { string name= ObjectName(i); if (StringSubstr(name,0,7)=="[PIVOT]") ObjectDelete(name); } return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { static datetime timelastupdate= 0; static datetime lasttimeframe= 0; datetime startofday= 0, startofyesterday= 0; double today_high= 0, today_low= 0, today_open= 0, yesterday_high= 0, yesterday_open= 0, yesterday_low= 0, yesterday_close= 0; int idxfirstbaroftoday= 0, idxfirstbarofyesterday= 0, idxlastbarofyesterday= 0; // no need to update these buggers too often if (CurTime()-timelastupdate < 600 && Period()==lasttimeframe) return (0); lasttimeframe= Period(); timelastupdate= CurTime(); //---- exit if period is greater than daily charts if(Period() > 1440) { Alert("Error - Chart period is greater than 1 day."); return(-1); // then exit } if (DebugLogger) { Print("Local time current bar:", TimeToStr(iTime(NULL, PERIOD_H1, 0))); Print("Dest time current bar: ", TimeToStr(iTime(NULL, PERIOD_H1, 0)- (LocalTimeZone - DestTimeZone)*3600), ", tzdiff= ", LocalTimeZone - DestTimeZone); } // let's find out which hour bars make today and yesterday ComputeDayIndices(LocalTimeZone, DestTimeZone, idxfirstbaroftoday, idxfirstbarofyesterday, idxlastbarofyesterday); startofday= iTime(NULL, PERIOD_H1, idxfirstbaroftoday); // datetime (x-value) for labes on horizontal bars startofyesterday= iTime(NULL, PERIOD_H1, idxfirstbarofyesterday); // datetime (x-value) for labes on horizontal bars // // walk forward through yestday's start and collect high/lows within the same day // yesterday_high= -99999; // not high enough to remain alltime high yesterday_low= +99999; // not low enough to remain alltime low for (int idxbar= idxfirstbarofyesterday; idxbar>=idxlastbarofyesterday; idxbar--) { if (yesterday_open==0) // grab first value for open yesterday_open= iOpen(NULL, PERIOD_H1, idxbar); yesterday_high= MathMax(iHigh(NULL, PERIOD_H1, idxbar), yesterday_high); yesterday_low= MathMin(iLow(NULL, PERIOD_H1, idxbar), yesterday_low); // overwrite close in loop until we leave with the last iteration's value yesterday_close= iClose(NULL, PERIOD_H1, idxbar); } // // walk forward through today and collect high/lows within the same day // today_open= iOpen(NULL, PERIOD_H1, idxfirstbaroftoday); // should be open of today start trading hour today_high= -99999; // not high enough to remain alltime high today_low= +99999; // not low enough to remain alltime low for (int j= idxfirstbaroftoday; j>=0; j--) { today_high= MathMax(today_high, iHigh(NULL, PERIOD_H1, j)); today_low= MathMin(today_low, iLow(NULL, PERIOD_H1, j)); } // draw the vertical bars that marks the time span double level= (yesterday_high + yesterday_low + yesterday_close) / 3; SetTimeLine("YesterdayStart", "yesterday", idxfirstbarofyesterday, CadetBlue, level - 4*Point); SetTimeLine("YesterdayEnd", "today", idxfirstbaroftoday, CadetBlue, level - 4*Point); if (DebugLogger) Print("Timezoned values: yo= ", yesterday_open, ", yc =", yesterday_close, ", yhigh= ", yesterday_high, ", ylow= ", yesterday_low, ", to= ", today_open); // //---- Calculate Levels // double p, q, d, r1,r2,r3, s1,s2,s3; d = (today_high - today_low); q = (yesterday_high - yesterday_low); p = (yesterday_high + yesterday_low + yesterday_close) / 3; r1 = (2*p)-yesterday_low; r2 = p+(yesterday_high - yesterday_low); // r2 = p-s1+r1; r3 = (2*p)+(yesterday_high-(2*yesterday_low)); s1 = (2*p)-yesterday_high; s2 = p-(yesterday_high - yesterday_low); // s2 = p-r1+s1; s3 = (2*p)-((2* yesterday_high)-yesterday_low); //---- High/Low, Open if (ShowHighLowOpen) { SetLevel("Y\'s High", yesterday_high, Orange, LineStyle, startofyesterday); SetLevel("T\'s Open", today_open, Orange, LineStyle, startofday); SetLevel("Y\'s Low", yesterday_low, Orange, LineStyle, startofyesterday); } //---- High/Low, Open if (ShowSweetSpots) { int ssp1, ssp2; double ds1, ds2; ssp1= Bid / Point; ssp1= ssp1 - ssp1%50; ssp2= ssp1 + 50; ds1= ssp1*Point; ds2= ssp2*Point; SetLevel(DoubleToStr(ds1,Digits), ds1, Gold, LineStyle, Time[10]); SetLevel(DoubleToStr(ds2,Digits), ds2, Gold, LineStyle, Time[10]); } //---- Pivot Lines if (ShowPivots==true) { SetLevel("R1", r1, Blue, LineStyle, startofday); SetLevel("R2", r2, Blue, LineStyle, startofday); SetLevel("R3", r3, Blue, LineStyle, startofday); SetLevel("Pivot", p, Magenta, LineStyle, startofday); SetLevel("S1", s1, Red, LineStyle, startofday); SetLevel("S2", s2, Red, LineStyle, startofday); SetLevel("S3", s3, Red, LineStyle, startofday); } //---- Fibos of yesterday's range if (ShowFibos) { // .618, .5 and .382 SetLevel("Low - 61.8%", yesterday_low - q*0.618, Yellow, LineStyle, startofday); SetLevel("Low - 38.2%", yesterday_low - q*0.382, Yellow, LineStyle, startofday); SetLevel("Low + 38.2%", yesterday_low + q*0.382, Yellow, LineStyle, startofday); SetLevel("LowHigh 50%", yesterday_low + q*0.5, Yellow, LineStyle, startofday); SetLevel("High - 38.2%", yesterday_high - q*0.382, Yellow, LineStyle, startofday); SetLevel("High + 38.2%", yesterday_high + q*0.382, Yellow, LineStyle, startofday); SetLevel("High + 61.8%", yesterday_high + q*0.618, Yellow, LineStyle, startofday); } //----- Camarilla Lines if (ShowCamarilla==true) { double h4,h3,l4,l3; h4 = (q*0.55)+yesterday_close; h3 = (q*0.27)+yesterday_close; l3 = yesterday_close-(q*0.27); l4 = yesterday_close-(q*0.55); SetLevel("H3", h3, Khaki, LineStyle, startofday); SetLevel("H4", h4, Khaki, LineStyle, startofday); SetLevel("L3", l3, Khaki, LineStyle, startofday); SetLevel("L4", l4, Khaki, LineStyle, startofday); } //------ Midpoints Pivots if (ShowMidPitvot==true) { // mid levels between pivots SetLevel("MR3", (r2+r3)/2, Green, LineStyle, startofday); SetLevel("MR2", (r1+r2)/2, Green, LineStyle, startofday); SetLevel("MR1", (p+r1)/2, Green, LineStyle, startofday); SetLevel("MS1", (p+s1)/2, Green, LineStyle, startofday); SetLevel("MS2", (s1+s2)/2, Green, LineStyle, startofday); SetLevel("MS3", (s2+s3)/2, Green, LineStyle, startofday); } //------ Comment for upper left corner if (ShowComment) { string comment; comment= comment + "-- Good luck with your trading! ---\n"; comment= comment + "Range: Yesterday "+DoubleToStr(MathRound(q/Point),0) +" pips, Today "+DoubleToStr(MathRound(d/Point),0)+" pips" + "\n"; comment= comment + "Highs: Yesterday "+DoubleToStr(yesterday_high,Digits) +", Today "+DoubleToStr(today_high,Digits) +"\n"; comment= comment + "Lows: Yesterday "+DoubleToStr(yesterday_low,Digits) +", Today "+DoubleToStr(today_low,Digits) +"\n"; comment= comment + "Close: Yesterday "+DoubleToStr(yesterday_close,Digits) + "\n"; comment= comment + "Pivot: " + DoubleToStr(p,Digits) + ", S1/2/3: " + DoubleToStr(s1,Digits) + "/" + DoubleToStr(s2,Digits) + "/" + DoubleToStr(s3,Digits) + "\n" ; comment= comment + "Fibos: " + DoubleToStr(yesterday_low + q*0.382, Digits) + ", " + DoubleToStr(yesterday_high - q*0.382,Digits) + "\n"; Comment(comment); } return(0); } //+------------------------------------------------------------------+ //| Compute index of first/last bar of yesterday and today | //+------------------------------------------------------------------+ void ComputeDayIndices(int tzlocal, int tzdest, int &idxfirstbaroftoday, int &idxfirstbarofyesterday, int &idxlastbarofyesterday) { int tzdiff= tzlocal - tzdest, tzdiffsec= tzdiff*3600; int dayofweektoday= TimeDayOfWeek(iTime(NULL, PERIOD_H1, 0) - tzdiffsec), // what day is today in the dest timezone? dayofweektofind= -1; // // due to gaps in the data, and shift of time around weekends (due // to time zone) it is not as easy as to just look back for a bar // with 00:00 time // idxfirstbaroftoday= 0; idxfirstbarofyesterday= 0; idxlastbarofyesterday= 0; switch (dayofweektoday) { case 6: // sat case 0: // sun case 1: // mon dayofweektofind= 5; // yesterday in terms of trading was previous friday break; default: dayofweektofind= dayofweektoday -1; break; } if (DebugLogger) { Print("Dayofweektoday= ", dayofweektoday); Print("Dayofweekyesterday= ", dayofweektofind); } // search backwards for the last occrrence (backwards) of the day today (today's first bar) for (int i=1; i<=25; i++) { datetime timet= iTime(NULL, PERIOD_H1, i) - tzdiffsec; if (TimeDayOfWeek(timet)!=dayofweektoday) { idxfirstbaroftoday= i-1; break; } } // search backwards for the first occrrence (backwards) of the weekday we are looking for (yesterday's last bar) for (int j= 0; j<=48; j++) { datetime timey= iTime(NULL, PERIOD_H1, i+j) - tzdiffsec; if (TimeDayOfWeek(timey)==dayofweektofind) { // ignore saturdays (a Sa may happen due to TZ conversion) idxlastbarofyesterday= i+j; break; } } // search backwards for the first occurrence of weekday before yesterday (to determine yesterday's first bar) for (j= 1; j<=24; j++) { datetime timey2= iTime(NULL, PERIOD_H1, idxlastbarofyesterday+j) - tzdiffsec; if (TimeDayOfWeek(timey2)!=dayofweektofind) { // ignore saturdays (a Sa may happen due to TZ conversion) idxfirstbarofyesterday= idxlastbarofyesterday+j-1; break; } } if (DebugLogger) { Print("Dest time zone\'s current day starts:", TimeToStr(iTime(NULL, PERIOD_H1, idxfirstbaroftoday)), " (local time), idxbar= ", idxfirstbaroftoday); Print("Dest time zone\'s previous day starts:", TimeToStr(iTime(NULL, PERIOD_H1, idxfirstbarofyesterday)), " (local time), idxbar= ", idxfirstbarofyesterday); Print("Dest time zone\'s previous day ends:", TimeToStr(iTime(NULL, PERIOD_H1, idxlastbarofyesterday)), " (local time), idxbar= ", idxlastbarofyesterday); } } //+------------------------------------------------------------------+ //| Helper | //+------------------------------------------------------------------+ void SetLevel(string text, double level, color col1, int linestyle, datetime startofday) { int digits= Digits; string labelname= "[PIVOT] " + text + " Label", linename= "[PIVOT] " + text + " Line", pricelabel; // create or move the horizontal line if (ObjectFind(linename) != 0) { ObjectCreate(linename, OBJ_TREND, 0, startofday, level, Time[0],level); ObjectSet(linename, OBJPROP_STYLE, linestyle); ObjectSet(linename, OBJPROP_COLOR, col1); } else { ObjectMove(linename, 1, Time[0],level); ObjectMove(linename, 0, startofday, level); } // put a label on the line if (ObjectFind(labelname) != 0) { ObjectCreate(labelname, OBJ_TEXT, 0, MathMin(Time[BarForLabels], startofday + 2*Period()*60), level); } else { ObjectMove(labelname, 0, MathMin(Time[BarForLabels], startofday+2*Period()*60), level); } pricelabel= " " + text; if (ShowLevelPrices && StrToInteger(text)==0) pricelabel= pricelabel + ": "+DoubleToStr(level, Digits); ObjectSetText(labelname, pricelabel, 8, "Arial", White); } //+------------------------------------------------------------------+ //| Helper | //+------------------------------------------------------------------+ void SetTimeLine(string objname, string text, int idx, color col1, double vleveltext) { string name= "[PIVOT] " + objname; int x= iTime(NULL, PERIOD_H1, idx); if (ObjectFind(name) != 0) ObjectCreate(name, OBJ_TREND, 0, x, 0, x, 100); else { ObjectMove(name, 0, x, 0); ObjectMove(name, 1, x, 100); } ObjectSet(name, OBJPROP_STYLE, STYLE_DOT); ObjectSet(name, OBJPROP_COLOR, DarkGray); if (ObjectFind(name + " Label") != 0) ObjectCreate(name + " Label", OBJ_TEXT, 0, x, vleveltext); else ObjectMove(name + " Label", 0, x, vleveltext); ObjectSetText(name + " Label", text, 8, "Arial", col1); }