//+------------------------------------------------------------------+ //| shved_supply_and_demand.mq4 | //+------------------------------------------------------------------+ #property copyright "Shved" #property link "http://ruforum_mt5_com/members/11434-shved" #property description "edited by eevviill" #property description "on-off zones,build 600+,nearest zones in buffers" #property indicator_chart_window #property indicator_buffers 8 #property indicator_color1 Red #property indicator_color2 Red #property indicator_color3 DodgerBlue #property indicator_color4 DodgerBlue extern int BackLimit=1000; extern string pus1="/////////////////////////////////////////////////"; extern bool zone_show_weak=true; extern bool zone_show_untested = true; extern bool zone_show_turncoat = false; extern double zone_fuzzfactor=0.75; extern string pus2="/////////////////////////////////////////////////"; extern bool fractals_show=false; extern double fractal_fast_factor = 3.0; extern double fractal_slow_factor = 6.0; extern bool SetGlobals=true; extern string pus3="/////////////////////////////////////////////////"; extern bool zone_solid=true; extern int zone_linewidth=1; extern int zone_style=0; extern bool zone_show_info=true; extern int zone_label_shift=4; extern bool zone_merge=true; extern bool zone_extend=true; extern string pus4="/////////////////////////////////////////////////"; extern bool zone_show_alerts = false; extern bool zone_alert_popups = true; extern bool zone_alert_sounds = true; extern int zone_alert_waitseconds=300; extern string pus5="/////////////////////////////////////////////////"; extern int Text_size=8; extern string Text_font = "Courier New"; extern color Text_color = White; extern string sup_name = "Sup"; extern string res_name = "Res"; extern string test_name= "Retests"; extern color color_support_weak = DarkSlateGray; extern color color_support_untested = SeaGreen; extern color color_support_verified = Green; extern color color_support_proven = LimeGreen; extern color color_support_turncoat = OliveDrab; extern color color_resist_weak = Indigo; extern color color_resist_untested = Orchid; extern color color_resist_verified = Crimson; extern color color_resist_proven = Red; extern color color_resist_turncoat = DarkOrange; double FastDnPts[],FastUpPts[]; double SlowDnPts[],SlowUpPts[]; double zone_hi[1000],zone_lo[1000]; int zone_start[1000],zone_hits[1000],zone_type[1000],zone_strength[1000],zone_count=0; bool zone_turn[1000]; #define ZONE_SUPPORT 1 #define ZONE_RESIST 2 #define ZONE_WEAK 0 #define ZONE_TURNCOAT 1 #define ZONE_UNTESTED 2 #define ZONE_VERIFIED 3 #define ZONE_PROVEN 4 #define UP_POINT 1 #define DN_POINT -1 int time_offset=0; double ner_lo_zone_P1[]; double ner_lo_zone_P2[]; double ner_hi_zone_P1[]; double ner_hi_zone_P2[]; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int init() { IndicatorBuffers(4); SetIndexBuffer(0,SlowDnPts); SetIndexBuffer(1,SlowUpPts); SetIndexBuffer(2,FastDnPts); SetIndexBuffer(3,FastUpPts); if(fractals_show==true) { SetIndexStyle(0,DRAW_ARROW,0,3); SetIndexStyle(1,DRAW_ARROW,0,3); SetIndexStyle(2,DRAW_ARROW,0,1); SetIndexStyle(3,DRAW_ARROW,0,1); SetIndexArrow(0,218); SetIndexArrow(1,217); SetIndexArrow(2,218); SetIndexArrow(3,217); } else { SetIndexStyle(0,DRAW_NONE); SetIndexStyle(1,DRAW_NONE); SetIndexStyle(2,DRAW_NONE); SetIndexStyle(3,DRAW_NONE); } SetIndexBuffer(4,ner_hi_zone_P1); SetIndexBuffer(5,ner_hi_zone_P2); SetIndexBuffer(6,ner_lo_zone_P1); SetIndexBuffer(7,ner_lo_zone_P2); SetIndexStyle(4,DRAW_NONE); SetIndexStyle(5,DRAW_NONE); SetIndexStyle(6,DRAW_NONE); SetIndexStyle(7,DRAW_NONE); SetIndexLabel(4,"ner up zone P1"); SetIndexLabel(5,"ner up zone P2"); SetIndexLabel(6,"ner dn zone P1"); SetIndexLabel(7,"ner dn zone P2"); IndicatorDigits(Digits); return(0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int deinit() { DeleteZones(); DeleteGlobalVars(); return(0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int start() { if(NewBar()==true) { int old_zone_count=zone_count; FastFractals(); SlowFractals(); DeleteZones(); FindZones(); DrawZones(); if(zone_count0 && zone_strength[i]>ZONE_UNTESTED) { if(zone_hits[i]==1) lbl=lbl+", "+test_name+"="+zone_hits[i]; else lbl=lbl+", "+test_name+"="+zone_hits[i]; } int adjust_hpos; int wbpc=WindowBarsPerChart(); int k=Period()*60+(20+StringLen(lbl)); if(wbpc<80) adjust_hpos=Time[0]+k*4; else if(wbpc<125) adjust_hpos=Time[0]+k*8; else if(wbpc<250) adjust_hpos=Time[0]+k*15; else if(wbpc<480) adjust_hpos=Time[0]+k*29; else if(wbpc<950) adjust_hpos=Time[0]+k*58; else adjust_hpos=Time[0]+k*115; // int shift=k*zone_label_shift; double vpos=zone_hi[i]-(zone_hi[i]-zone_lo[i])/2; if(zone_strength[i]==ZONE_WEAK && zone_show_weak==false) continue; if(zone_strength[i]==ZONE_UNTESTED && zone_show_untested==false) continue; if(zone_strength[i]==ZONE_TURNCOAT && zone_show_turncoat==false) continue; string s="SSSR#"+i+"LBL"; ObjectCreate(s,OBJ_TEXT,0,0,0); ObjectSet(s,OBJPROP_TIME1,adjust_hpos+shift); ObjectSet(s,OBJPROP_PRICE1,vpos); ObjectSetText(s,StringRightPad(lbl,36," "),Text_size,Text_font,Text_color); } } CheckAlerts(); return(0); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CheckAlerts() { static int lastalert=0; if(zone_show_alerts==false) return; if(Time[0]-lastalert>zone_alert_waitseconds) if(CheckEntryAlerts()==true) lastalert=Time[0]; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool CheckEntryAlerts() { // check for entries for(int i=0; i=zone_lo[i] && Close[0]5; shift--) { double atr= iATR(NULL,0,7,shift); double fu = atr/2 * zone_fuzzfactor; bool isWeak; bool touchOk= false; bool isBust = false; if(FastUpPts[shift]>0.001) { // a zigzag high point isWeak=true; if(SlowUpPts[shift]>0.001) isWeak=false; hival=High[shift]; if(zone_extend==true) hival+=fu; loval=MathMax(MathMin(Close[shift],High[shift]-fu),High[shift]-fu*2); turned=false; hasturned=false; isBust=false; bustcount = 0; testcount = 0; for(i=shift-1; i>=0; i--) { if((turned==false && FastUpPts[i]>=loval && FastUpPts[i]<=hival) || (turned==true && FastDnPts[i]<=hival && FastDnPts[i]>=loval)) { // Potential touch, just make sure its been 10+candles since the prev one touchOk=true; for(j=i+1; j=loval && FastUpPts[j]<=hival) || (turned==true && FastDnPts[j]<=hival && FastDnPts[j]>=loval)) { touchOk=false; break; } } if(touchOk==true) { // we have a touch_ If its been busted once, remove bustcount // as we know this level is still valid & has just switched sides bustcount=0; testcount++; } } if((turned==false && High[i]>hival) || (turned==true && Low[i]1 || isWeak==true) { // busted twice or more isBust=true; break; } if(turned == true) turned = false; else if(turned==false) turned=true; hasturned=true; // forget previous hits testcount=0; } } if(isBust==false) { // level is still valid, add to our list temp_hi[temp_count] = hival; temp_lo[temp_count] = loval; temp_turn[temp_count] = hasturned; temp_hits[temp_count] = testcount; temp_start[temp_count] = shift; temp_merge[temp_count] = false; if(testcount>3) temp_strength[temp_count]=ZONE_PROVEN; else if(testcount>0) temp_strength[temp_count]=ZONE_VERIFIED; else if(hasturned==true) temp_strength[temp_count]=ZONE_TURNCOAT; else if(isWeak==false) temp_strength[temp_count]=ZONE_UNTESTED; else temp_strength[temp_count]=ZONE_WEAK; temp_count++; } } else if(FastDnPts[shift]>0.001) { // a zigzag low point isWeak=true; if(SlowDnPts[shift]>0.001) isWeak=false; loval=Low[shift]; if(zone_extend==true) loval-=fu; hival=MathMin(MathMax(Close[shift],Low[shift]+fu),Low[shift]+fu*2); turned=false; hasturned=false; bustcount = 0; testcount = 0; isBust=false; for(i=shift-1; i>=0; i--) { if((turned==true && FastUpPts[i]>=loval && FastUpPts[i]<=hival) || (turned==false && FastDnPts[i]<=hival && FastDnPts[i]>=loval)) { // Potential touch, just make sure its been 10+candles since the prev one touchOk=true; for(j=i+1; j=loval && FastUpPts[j]<=hival) || (turned==false && FastDnPts[j]<=hival && FastDnPts[j]>=loval)) { touchOk=false; break; } } if(touchOk==true) { // we have a touch_ If its been busted once, remove bustcount // as we know this level is still valid & has just switched sides bustcount=0; testcount++; } } if((turned==true && High[i]>hival) || (turned==false && Low[i]1 || isWeak==true) { // busted twice or more isBust=true; break; } if(turned == true) turned = false; else if(turned==false) turned=true; hasturned=true; // forget previous hits testcount=0; } } if(isBust==false) { // level is still valid, add to our list temp_hi[temp_count] = hival; temp_lo[temp_count] = loval; temp_turn[temp_count] = hasturned; temp_hits[temp_count] = testcount; temp_start[temp_count] = shift; temp_merge[temp_count] = false; if(testcount>3) temp_strength[temp_count]=ZONE_PROVEN; else if(testcount>0) temp_strength[temp_count]=ZONE_VERIFIED; else if(hasturned==true) temp_strength[temp_count]=ZONE_TURNCOAT; else if(isWeak==false) temp_strength[temp_count]=ZONE_UNTESTED; else temp_strength[temp_count]=ZONE_WEAK; temp_count++; } } } // look for overlapping zones___ if(zone_merge==true) { merge_count=1; int iterations=0; while(merge_count>0 && iterations<3) { merge_count=0; iterations++; for(i=0; i=temp_lo[j] && temp_hi[i]<=temp_hi[j]) || (temp_lo[i] <= temp_hi[j] && temp_lo[i] >= temp_lo[j]) || (temp_hi[j] >= temp_lo[i] && temp_hi[j] <= temp_hi[i]) || (temp_lo[j] <= temp_hi[i] && temp_lo[j] >= temp_lo[i])) { merge1[merge_count] = i; merge2[merge_count] = j; temp_merge[i] = true; temp_merge[j] = true; merge_count++; } } } // ___ and merge them ___ for(i=0; i3) temp_strength[target]=ZONE_PROVEN; if(temp_hits[target]==0 && temp_turn[target]==false) { temp_hits[target]=1; if(temp_strength[target]=0 && zone_count<1000) { zone_hi[zone_count] = temp_hi[i]; zone_lo[zone_count] = temp_lo[i]; zone_hits[zone_count] = temp_hits[i]; zone_turn[zone_count] = temp_turn[i]; zone_start[zone_count] = temp_start[i]; zone_strength[zone_count] = temp_strength[i]; if(zone_hi[zone_count]Close[4]) zone_type[zone_count]=ZONE_RESIST; else { for(j=5; j<1000; j++) { if(Close[j]zone_hi[zone_count]) { zone_type[zone_count]=ZONE_SUPPORT; break; } } if(j==1000) zone_type[zone_count]=ZONE_SUPPORT; } zone_count++; } } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void DrawZones() { double lower_nerest_zone_P1=0; double lower_nerest_zone_P2=0; double higher_nerest_zone_P1=EMPTY_VALUE; double higher_nerest_zone_P2=EMPTY_VALUE; if(SetGlobals==true) { GlobalVariableSet("SSSR_Count_"+Symbol()+Period(),zone_count); GlobalVariableSet("SSSR_Updated_"+Symbol()+Period(),TimeCurrent()); } for(int i=0; ilower_nerest_zone_P2 && Bid>zone_lo[i]) {lower_nerest_zone_P1=zone_hi[i];lower_nerest_zone_P2=zone_lo[i];} if(zone_hi[i]P) P=Period(); P=P/Period()*2+MathCeil(P/Period()/2); if(shiftBars-P) return(false); for(int i=1; i<=P; i++) { if(M==UP_POINT) { if(High[shift+i]>High[shift]) return(false); if(High[shift-i]>=High[shift]) return(false); } if(M==DN_POINT) { if(Low[shift+i]1; shift--) { if(Fractal(UP_POINT,P,shift)==true) FastUpPts[shift]=High[shift]; else FastUpPts[shift]=0.0; if(Fractal(DN_POINT,P,shift)==true) FastDnPts[shift]=Low[shift]; else FastDnPts[shift]=0.0; } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void SlowFractals() { int shift; int limit=MathMin(Bars-1,BackLimit); int P=Period()*fractal_slow_factor; SlowUpPts[0] = 0.0; SlowUpPts[1] = 0.0; SlowDnPts[0] = 0.0; SlowDnPts[1] = 0.0; for(shift=limit; shift>1; shift--) { if(Fractal(UP_POINT,P,shift)==true) SlowUpPts[shift]=High[shift]; else SlowUpPts[shift]=0.0; if(Fractal(DN_POINT,P,shift)==true) SlowDnPts[shift]=Low[shift]; else SlowDnPts[shift]=0.0; } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ bool NewBar() { static datetime LastTime=0; if(iTime(Symbol(),Period(),0)+time_offset!=LastTime) { LastTime=iTime(Symbol(),Period(),0)+time_offset; return (true); } else return (false); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void DeleteZones() { int len=5; int i; while(i