VKW Bands V2
Download scriptThis script functions as a visual trading tool designed to identify specific price action patterns and potential entry points by analyzing historical data and current market movements. It operates by layering several mathematical calculations to "filter" out market noise, focusing on the significant boundaries of price movement.
Core Analytical Logic
The indicator works through a multi-step processing sequence:
1. Data Gathering and Range Identification The script first looks at a specific window of recent history (the "Range Period"). Within this window, it identifies the highest and lowest price points reached. By isolating these extremes, the tool establishes the current "envelope" of the market's volatility.
2. Smoothing and Trend Filtering To prevent the indicator from reacting to minor, insignificant price flickers, it applies a smoothing calculation (a Moving Average) to those high and low boundaries. This transforms jagged price edges into fluid lines. These smoothed lines represent the dynamic "ceiling" and "floor" of the market trend.
3. Crossing Logic and Signal Generation The primary logic relies on monitoring when the actual market price crosses these smoothed boundaries:
- Bullish Signals: The script tracks instances where the price moves above the upper boundary (the ceiling). If the price then pulls back slightly but remains in a specific relationship to that ceiling, the script triggers a visual alert.
- Bearish Signals: Conversely, it monitors when the price drops below the lower boundary (the floor). If the price rebounds slightly but stays near that floor, it identifies a potential downward move.
Visual Elements and User Experience
Instead of just providing numbers, the script interacts directly with your chart to make analysis easier:
- Dynamic Markers: When a signal is triggered, the script automatically places colored arrows on the chart to highlight exactly where the price action met the criteria.
- Support and Resistance Lines: It draws horizontal trend lines at key levels to help the user visualize where the "floors" and "ceilings" are currently sitting.
- Fractal Recognition: The script includes a specialized search function that looks for "fractals"—specific patterns in price geometry. This helps verify if a turn in the market is significant enough to be considered a valid structural change rather than a random fluctuation.
- Automatic Cleanup: The logic includes a management system that clears out old drawing objects at regular intervals. This ensures that your chart remains clean and is only populated with the most relevant, current data.
Summary for the User
In simple terms, this tool acts like a "boundary watcher." It identifies the high and low reaches of recent price action, smooths them out to find the true trend, and then places visual markers on the chart whenever the price interacts with those boundaries in a way that suggests a potential reversal or a continuation of a move.
//+------------------------------------------------------------------+
//| VKW Bands.mq4 |
//| Copyright © 2008, MetaQuotes Software Corp. |
//| http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Alksnis Gatis"
#property link "2xpoint@gmail.com"
//----
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 Blue
#property indicator_color2 Red
#property indicator_color3 White
#property indicator_width2 2
//---- input parameters
extern int RangePeriod=25;
extern int SmoothPeriod=3;
extern int SmoothMode=MODE_SMA;
extern int Per=5;
//---- buffers
double ExtMapBuffer0[];
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
double ExtMapBuffer4[];
bool fb=false, fs=false;
double a[],t[],fa,fd;
int i, b;
datetime drop=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init(){
//---- indicators
IndicatorBuffers(5);
SetIndexStyle(0,DRAW_LINE);
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexDrawBegin(0,SmoothPeriod);
SetIndexStyle(1,DRAW_LINE);
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexDrawBegin(1,SmoothPeriod);
SetIndexBuffer(2,ExtMapBuffer0);
SetIndexBuffer(3,ExtMapBuffer3);
SetIndexBuffer(4,ExtMapBuffer4);
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit(){
//----
ObjectsDeleteAll();
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start(){
int counted_bars=IndicatorCounted();
//----
if(drop==0)drop=TimeCurrent()+60;
if(drop<=TimeCurrent()){
bool qwe=false;
for(i=0;i<=30;i++){
if(ObjectFind("ui"+i) >0) {ObjectDelete("ui"+i); }
if(ObjectFind("uw"+i) >0) {ObjectDelete("uw"+i); }
if(ObjectFind("txtu"+i)>0) {ObjectDelete("txtu"+i);}
if(ObjectFind("tu"+i) >0) {ObjectDelete("tu"+i); }
if(ObjectFind("di"+i) >0) {ObjectDelete("di"+i); }
if(ObjectFind("dw"+i) >0) {ObjectDelete("dw"+i); }
if(ObjectFind("txtd"+i)>0) {ObjectDelete("txtd"+i);}
if(ObjectFind("td"+i) >0) {ObjectDelete("td"+i); }
}
drop=TimeCurrent()+60;
}
int limit,limit1,cnt,n_max,n_min;
if (counted_bars==0){
limit=Bars-RangePeriod;
limit1=limit-SmoothPeriod;
}
if (counted_bars>0){
limit=Bars-counted_bars;
limit1=limit;
}
limit--;
limit1--;
for(cnt=limit; cnt>=0;cnt--){
ExtMapBuffer0[cnt]=iCustom(NULL,0,"METRO",1,cnt);
}
for(cnt=limit; cnt>=0;cnt--){
n_max=ArrayMaximum(ExtMapBuffer0,RangePeriod,cnt);
n_min=ArrayMinimum(ExtMapBuffer0,RangePeriod,cnt);
ExtMapBuffer3[cnt]=ExtMapBuffer0[n_max];
ExtMapBuffer4[cnt]=ExtMapBuffer0[n_min];
}
for(cnt=limit1; cnt>=0;cnt--){
ExtMapBuffer1[cnt]=iMAOnArray(ExtMapBuffer3,0,SmoothPeriod,0,SmoothMode,cnt);
ExtMapBuffer2[cnt]=iMAOnArray(ExtMapBuffer4,0,SmoothPeriod,0,SmoothMode,cnt);
}
i=Bars-RangePeriod;
while(i>=0){
if(ExtMapBuffer0[i]>=ExtMapBuffer1[i])fs=true;
if(fs==true&&ExtMapBuffer0[i]+0.1<ExtMapBuffer1[i]){
SetArrow(242,Blue,"ui"+i,1,Time[i],ExtMapBuffer0[i],2);
SetArrow(242,Blue,"uw"+i,0,Time[i],High[i]+15*Point ,2);
fa=FindNearFractal(Symbol(),0,MODE_UPPER,i);
//SetText(Symbol(), "txtu"+b, "BUYSTOP "+DoubleToStr(High[b],Digits), Yellow, Time[b]+3*3600, High[b], 8, 0, 1);
SetTLine(Yellow, "tu"+b, Time[b]-5*3600, High[b], Time[b]+15*3600, High[b], false, 0, 2, 0);
fs=false;
}
if(ExtMapBuffer0[i]<=ExtMapBuffer2[i])fb=true;
if(fb==true&&ExtMapBuffer0[i]-0.1>ExtMapBuffer2[i]){
SetArrow(241,Yellow,"di"+i,1,Time[i],ExtMapBuffer0[i],2);
SetArrow(241,Yellow,"dw"+i,0,Time[i],Low[i]-2*Point ,2);
fd=FindNearFractal(Symbol(),0,MODE_LOWER,i);
//SetText(Symbol(), "txtd"+b, "SELLSTOP "+DoubleToStr(Low[b],Digits), Yellow, Time[b]+3*3600, Low[b], 8, 0, -1);
SetTLine(Red, "td"+b, Time[b]-5*3600, Low[b], Time[b]+15*3600, Low[b], false, 0, 2, 0);
fb=false;
}
i--;
WindowRedraw();
}
//----
return(0);
}
//+----------------------------------------------------------------------------+
//| Àâòîð : Êèì Èãîðü Â. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Âåðñèÿ : 12.10.2007 |
//| Îïèñàíèå : Óñòàíîâêà çíà÷êà íà ãðàôèêå, îáúåêòà OBJ_ARROW. |
//+----------------------------------------------------------------------------+
//| Ïàðàìåòðû: |
//| cd - êîä çíà÷êà |
//| cl - öâåò çíà÷êà |
//| nm - íàèìåíîâàíèå ("" - âðåìÿ îòêðûòèÿ òåêóùåãî áàðà) |
//| t1 - âðåìÿ îòêðûòèÿ áàðà (0 - òåêóùèé áàð) |
//| p1 - öåíîâîé óðîâåíü (0 - Bid) |
//| sz - ðàçìåð çíà÷êà (0 - ïî óìîë÷àíèþ) |
//| w - îêíî îòðèñîâêè (0 - îñíîâíîå îêíî) |
//+----------------------------------------------------------------------------+
void SetArrow(int cd, color cl, string nm="", int w=0, datetime t1=0, double p1=0, int sz=0) {
if (nm=="") nm=DoubleToStr(Time[0], 0);
if (t1<=0) t1=Time[0];
if (p1<=0) p1=Bid;
if (ObjectFind(nm)<0) ObjectCreate(nm, OBJ_ARROW, w, 0,0);
ObjectSet(nm, OBJPROP_TIME1 , t1);
ObjectSet(nm, OBJPROP_PRICE1 , p1);
ObjectSet(nm, OBJPROP_ARROWCODE, cd);
ObjectSet(nm, OBJPROP_COLOR , cl);
ObjectSet(nm, OBJPROP_WIDTH , sz);
}/*
void SetText(string sy, string nm, string tx, color cl, datetime t1=0, double p1=0, int fs=9, int w=0, int pos=1){
int d=MarketInfo(sy, MODE_DIGITS);
if (nm=="") nm=DoubleToStr(Time[0], 0);
if (ObjectFind(nm)<0) ObjectCreate(nm, OBJ_TEXT, w, 0,0);
if (d==0) if (StringFind(sy, "JPY")<0) d=4; else d=2;
if (pos!=1) pos=-1;
p1=NormalizeDouble(p1, d);
ObjectSetText(nm, tx, fs);
ObjectSet(nm, OBJPROP_COLOR, cl);
ObjectSet(nm, OBJPROP_TIME1 , t1);
if(pos==1 && sy=="EURUSD")ObjectSet(nm,OBJPROP_PRICE1,p1+0.0015);
if(pos==-1 && sy=="EURUSD")ObjectSet(nm,OBJPROP_PRICE1,p1-0.0002);
if(pos==1 && sy=="GBPUSD")ObjectSet(nm,OBJPROP_PRICE1,p1+0.0035);
if(pos==-1 && sy=="GBPUSD")ObjectSet(nm,OBJPROP_PRICE1,p1-0.0002);
if(pos==1 && sy=="USDCHF")ObjectSet(nm,OBJPROP_PRICE1,p1+0.0015);
if(pos==-1 && sy=="USDCHF")ObjectSet(nm,OBJPROP_PRICE1,p1-0.0002);
if(pos==1 && sy=="USDJPY")ObjectSet(nm,OBJPROP_PRICE1,p1+0.15);
if(pos==-1 && sy=="USDJPY")ObjectSet(nm,OBJPROP_PRICE1,p1-0.02);
if(pos==1 && sy=="EURJPY")ObjectSet(nm,OBJPROP_PRICE1,p1+0.30);
if(pos==-1 && sy=="EURJPY")ObjectSet(nm,OBJPROP_PRICE1,p1-0.02);
if(pos==1 && sy=="GBPJPY")ObjectSet(nm,OBJPROP_PRICE1,p1+0.45);
if(pos==-1 && sy=="GBPJPY")ObjectSet(nm,OBJPROP_PRICE1,p1-0.02);
ObjectSet(nm, OBJPROP_FONTSIZE, fs);
ObjectSet(nm, OBJPROP_BACK, false);
}
*/
//+----------------------------------------------------------------------------+
//| Àâòîð : Êèì Èãîðü Â. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Âåðñèÿ : 12.10.2007 |
//| Îïèñàíèå : Óñòàíîâêà òåêñòîâîé ìåòêè, îáúåêò OBJ_LABEL. |
//+----------------------------------------------------------------------------+
//| Ïàðàìåòðû: |
//| nm - íàèìåíîâàíèå îáúåêòà |
//| tx - òåêñò |
//| cl - öâåò ìåòêè |
//| xd - êîîðäèíàòà X â ïèêñåëàõ |
//| yd - êîîðäèíàòà Y â ïèêñåëàõ |
//| cr - íîìåð óãëà ïðèâÿçêè (0 - ëåâûé âåðõíèé, |
//| 1 - ïðàâûé âåðõíèé, |
//| 2 - ëåâûé íèæíèé, |
//| 3 - ïðàâûé íèæíèé ) |
//| fs - ðàçìåð øðèôòà (9 - ïî óìîë÷àíèþ ) |
//| w - îêíî îòðèñîâêè (0 - îñíîâíîå îêíî) |
//+----------------------------------------------------------------------------+
/*void SetLabel(string nm, string tx, color cl, int xd, int yd, int cr=0, int fs=9, int w=0){
if (ObjectFind(nm)<0) ObjectCreate(nm, OBJ_LABEL, w, 0,0);
ObjectSetText(nm, tx, fs);
ObjectSet(nm, OBJPROP_COLOR , cl);
ObjectSet(nm, OBJPROP_XDISTANCE, xd);
ObjectSet(nm, OBJPROP_YDISTANCE, yd);
ObjectSet(nm, OBJPROP_CORNER , cr);
ObjectSet(nm, OBJPROP_FONTSIZE , fs);
}*/
//+----------------------------------------------------------------------------+
//| Àâòîð : Êèì Èãîðü Â. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Âåðñèÿ : 12.10.2007 |
//| Îïèñàíèå : Óñòàíîâêà îáúåêòà OBJ_TREND òðåíäîâàÿ ëèíèÿ |
//+----------------------------------------------------------------------------+
//| Ïàðàìåòðû: |
//| cl - öâåò ëèíèè |
//| nm - íàèìåíîâàíèå ( "" - âðåìÿ îòêðûòèÿ òåêóùåãî áàðà) |
//| t1 - âðåìÿ îòêðûòèÿ áàðà ( 0 - Time[10] |
//| p1 - öåíîâîé óðîâåíü ( 0 - Low[10]) |
//| t2 - âðåìÿ îòêðûòèÿ áàðà ( 0 - òåêóùèé áàð) |
//| p2 - öåíîâîé óðîâåíü ( 0 - Bid) |
//| ry - ëó÷ (False - ïî óìîë÷àíèþ) |
//| st - ñòèëü ëèíèè ( 0 - ïðîñòàÿ ëèíèÿ) |
//| wd - øèðèíà ëèíèè ( 1 - ïî óìîë÷àíèþ) |
//| w - îêíî îòðèñîâêè ( 0 - îñíîâíîå îêíî) |
//+----------------------------------------------------------------------------+
void SetTLine(color cl, string nm="", datetime t1=0, double p1=0,
datetime t2=0, double p2=0, bool ry=False, int st=0, int wd=1, int w=0) {
if (nm=="") nm=DoubleToStr(Time[0], 0);
if (t1<=0) t1=Time[10];
if (p1<=0) p1=Low[10];
if (t2<=0) t2=Time[0];
if (p2<=0) p2=Bid;
if (ObjectFind(nm)<0) ObjectCreate(nm, OBJ_TREND, w, 0,0, 0,0);
ObjectSet(nm, OBJPROP_TIME1 , t1);
ObjectSet(nm, OBJPROP_PRICE1, p1);
ObjectSet(nm, OBJPROP_TIME2 , t2);
ObjectSet(nm, OBJPROP_PRICE2, p2);
ObjectSet(nm, OBJPROP_COLOR , cl);
ObjectSet(nm, OBJPROP_RAY , ry);
ObjectSet(nm, OBJPROP_STYLE , st);
ObjectSet(nm, OBJPROP_WIDTH , wd);
}
//+----------------------------------------------------------------------------+
//| Àâòîð : Êèì Èãîðü Â. aka KimIV, http://www.kimiv.ru |
//+----------------------------------------------------------------------------+
//| Âåðñèÿ : 07.10.2006 |
//| Îïèñàíèå : Ïîèñê áëèæàéøåãî ôðàêòàëà. |
//+----------------------------------------------------------------------------+
//| Ïàðàìåòðû: |
//| sy - íàèìåíîâàíèå èíñòðóìåíòà (NULL - òåêóùèé ñèìâîë) |
//| tf - òàéìôðåéì (0 - òåêóùèé ÒÔ) |
//| mode - òèï ôðàêòàëà (MODE_LOWER|MODE_UPPER) |
//| start - áàð ñ êîòîðîãî íåáõîäèìî íà÷èíàòü ïîèñê (2 - ïî óìîë÷àíèþ) |
//+----------------------------------------------------------------------------+
double FindNearFractal(string sy="0", int tf=0, int mode=MODE_LOWER, int start = 2) {
if (sy=="" || sy=="0") sy=Symbol();
double f=0;
int d=MarketInfo(sy, MODE_DIGITS), s;
if (d==0) if (StringFind(sy, "JPY")<0) d=4; else d=2;
for (s=start; s<start+50; s++) {
f=iFractals(sy, tf, mode, s);
if (f!=0){b=s; return(NormalizeDouble(f, d));}
}
Print("FindNearFractal(): Ôðàêòàë íå íàéäåí");
return(0);
}
//+----------------------------------------------------------------------------+
/*void FunNewBar(){
static datetime New_Time=0;
new_bar=false;
if(New_Time!=Time[0]){
New_Time=Time[0];
new_bar=true;
}
}*/
//+----------------------------------------------------------------------------+
Comments