K-Barishpoltz Channel
Download scriptThis script functions as an automated charting tool designed to identify and draw "Barishpoltz Channels" on a price graph. Instead of requiring a trader to manually draw trendlines or identify support and resistance levels, the logic automatically scans historical price data to find significant structural turning points.
Core Logic Overview
The script operates through three primary stages: Identification, Validation, and Drawing.
1. Identifying Extreme Points (Peaks and Troughs)
The tool first combs through the price history to locate "Extreme Peaks" and "Bottom Peaks." It doesn't just look at every high or low point; it uses specific criteria to ensure only significant structural points are selected:
- Relative Height: A peak or trough must meet a minimum height requirement (defined by the user) to be considered a valid turning point.
- Local Significance: The script ensures the point is higher than its immediate neighbors (for peaks) or lower than its immediate neighbors (for troughs).
- Spacing: It looks for points that are separated by a minimum distance to avoid cluttered data from minor price fluctuations.
2. Structural Analysis and Validation
Once the significant peaks and troughs are identified, the script attempts to connect them to form a channel. This is where the core "intelligence" of the script resides:
- Connectivity: It searches for the most logical pairings between top peaks and bottom troughs to create a cohesive geometric shape (the channel).
- Boundary Integrity (The "No-Breach" Rule): This is a critical step. Before drawing a line, the script performs a mathematical check on all price bars between the two points being connected.
- If any price bar in that period breaks through the proposed boundary (i.e., if a candle high pierces a top line or a low pierces a bottom line), the script rejects that specific connection.
- Only "clean" channels—where the boundaries remain unviolated by the price action—are selected for display.
3. Visual Rendering
After finding a valid, non-breached channel, the script renders three visual elements on the chart:
- Top Border: A line representing the upper limit of the trend.
- Bottom Border: A line representing the lower limit of the trend.
- Peak Markers: Specific icons or points that highlight the exact structural pivots used to anchor the channel.
Summary for the User
In essence, this script automates the "hunting" for stable price corridors. It filters out market noise by only highlighting channels that have successfully contained the price action without being breached. This allows a trader to see established structures where the market has historically respected boundaries, potentially identifying areas of support and resistance more accurately than drawing them by hand.
//+------------------------------------------------------------------+
//| Barishpoltz Channel.mq4 |
//| SaiborEye |
//| |
//+------------------------------------------------------------------+
#property copyright "SaiborEye"
#property link ""
/*
Ýòî ïðîáíûé âàðèàíò èíäèêàòîðà, âûïîëíÿþùåãî ïîñòðîåíèå è îòîáðàæåíèå
ïðåñëîâóòûõ ñêîëüçÿùèõ êàíàëîâ Áàðèøïîëüöà. Äàííûé ðåëèç ïðåäíàçíà÷åí
äëÿ ïðèêëàäíîé îöåíêè âîçìîæíîñòè îòêàçà îò ðó÷íîãî ïîñòðîåíèÿ, âûÿâëåíèÿ
è êîððåêöèè ñëàáûõ ìåñò, ïðåäëîæåíèÿ ïî ââîäó äîïîëíèòåëüíûõ ïàðàìåòðîâ
*/
#property indicator_chart_window
#property indicator_buffers 3
#property indicator_color1 Gold
#property indicator_color2 Coral
#property indicator_color3 Aquamarine
//---- input parameters
extern int RightLevel=3;// Îòñòóï îò ïðàâîé ãðàíèöû ãðàôèêà (Íîìåð áàðà, 0 - ïîñëåäíèé, íå ñôîðìèðîâàâøèéñÿ)
extern int BetweenPeaks=2;// Ìèíèìàëüíîå ðàññòîÿíèå ìåæäó ýêñòðåìóìàìè (êîëè÷åñòâî áàðîâ)
extern int MaxLength=600;// Ìàêñèìàëüíàÿ ðàçðåøåííàÿ äëèíà êàíàëà (êîëè÷åñòâî áàðîâ)
extern double PeakLevel=10.0;// Âûñîòà ïèêà, ïðåâûñèâ êîòîðóþ îí èìååò ïðàâî íàçûâàòüñÿ ýêñòðåìóìîì (ïóíêòû)
//---- buffers
double ExtMapBuffer1[];
double ExtMapBuffer2[];
double ExtMapBuffer3[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0,DRAW_SECTION);
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexEmptyValue(0,0.0);
SetIndexLabel(0,"Top Border");
SetIndexStyle(1,DRAW_SECTION);
SetIndexBuffer(1,ExtMapBuffer2);
SetIndexEmptyValue(1,0.0);
SetIndexLabel(1,"Bottom Border");
SetIndexStyle(2,DRAW_ARROW,STYLE_SOLID,3);
SetIndexBuffer(2,ExtMapBuffer3);
SetIndexEmptyValue(2,0.0);
SetIndexArrow(2,159);
SetIndexLabel(2,"Peak");
//----
PeakLevel*=Point;
return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
//+------------------------------------------------------------------+
int CheckBorders(int X1,int X2,int X3,double Y1,double Y2,double Y3){
int x,limit;
if(X1>X2)limit=X1;else limit=X2;
if(Y1>Y3&&Y2>Y3){// TOP TWO
for(x=0;x<limit;x++){// LINE LOOP-1
if(Y2+(x*1.0-X2*1.0)*(Y1-Y2)/(X1*1.0-X2*1.0)<High[x])return (1);
}// LINE LOOP-1
for(x=0;x<limit;x++){// LINE LOOP-2
if(Y3+(x*1.0-X3*1.0)*(Y1-Y2)/(X1*1.0-X2*1.0)>Low[x])return (-1);
}// LINE LOOP-2
return (0);
}// TOP TWO
if(Y1<Y3&&Y2<Y3){// BOTTOM TWO
for(x=0;x<limit;x++){// LINE LOOP-3
if(Y2+(x*1.0-X2*1.0)*(Y1-Y2)/(X1*1.0-X2*1.0)>Low[x])return (-1);
}// LINE LOOP-3
for(x=0;x<limit;x++){// LINE LOOP-4
if(Y3+(x*1.0-X3*1.0)*(Y1-Y2)/(X1*1.0-X2*1.0)<High[x])return (1);
}// LINE LOOP-4
return (0);
}// BOTTOM TWO
return (-1);}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int PosX1[2],PosX2,posminmax,pos,pos1,pos2,limit;//,counted_bars=IndicatorCounted();
double value;
bool Flag;
int TopPeaksPos[];
int TopPeaksIndex;
int BottomPeaksPos[];
int BottomPeaksIndex;
//----
limit=MaxLength;if(limit>Bars-2)limit=Bars-2;
ArrayResize(TopPeaksPos,limit);ArrayResize(BottomPeaksPos,limit);
TopPeaksIndex=0;BottomPeaksIndex=0;
ArrayInitialize(ExtMapBuffer1,0.0);ArrayInitialize(ExtMapBuffer2,0.0);ArrayInitialize(ExtMapBuffer3,0.0);
//----
for(pos=RightLevel;pos<limit;pos++){// MAIN LOOP
if(pos>RightLevel&&pos<limit-1)if(High[pos]>=High[pos-1]&&High[pos]>=High[pos+1]){// TOP PEAKS
Flag=TRUE;
for(pos1=pos-1;pos1>=RightLevel;pos1--){if(High[pos1]>High[pos]){Flag=FALSE;break;}
if(High[pos1]<=High[pos]-PeakLevel)break;}
if(Flag)if(pos1==RightLevel-1)Flag=FALSE;
if(Flag)for(pos1=pos+1;pos1<limit;pos1++){if(High[pos1]>High[pos]){Flag=FALSE;break;}
if(High[pos1]<=High[pos]-PeakLevel)break;}
if(Flag)if(pos1==limit)Flag=FALSE;
if(Flag){TopPeaksPos[TopPeaksIndex]=pos;TopPeaksIndex++;}
}// TOP PEAKS
//----
if(pos>RightLevel&&pos<limit-1)if(Low[pos]<=Low[pos-1]&&Low[pos]<=Low[pos+1]){// BOTTOM PEAKS
Flag=TRUE; for(pos1=pos-1;pos1>=RightLevel;pos1--){if(Low[pos1]<Low[pos]){Flag=FALSE;break;}
if(Low[pos1]>=Low[pos]+PeakLevel)break;}
if(Flag)if(pos1==RightLevel-1)Flag=FALSE;
if(Flag)for(pos1=pos+1;pos1<limit;pos1++){if(Low[pos1]<Low[pos]){Flag=FALSE;break;}
if(Low[pos1]>=Low[pos]+PeakLevel)break;}
if(Flag)if(pos1==limit)Flag=FALSE;
if(Flag){BottomPeaksPos[BottomPeaksIndex]=pos;BottomPeaksIndex++;}
}// BOTTOM PEAKS
}// MAIN LOOP
//----
if(BottomPeaksIndex>TopPeaksIndex)limit=BottomPeaksIndex;else limit=TopPeaksIndex;
for(pos=0;pos<limit;pos++){// SEEK LOOP
if(pos<TopPeaksIndex&&pos<BottomPeaksIndex)if(TopPeaksPos[pos]<BottomPeaksPos[pos]){// TOP NEARLY
for(pos1=pos;pos1<TopPeaksIndex;pos1++){// SECOND POINT SEEK
value=Low[BottomPeaksPos[pos]]+10000.0;posminmax=-1;
for(pos2=pos;BottomPeaksPos[pos2]<=TopPeaksPos[pos1] && BottomPeaksPos[pos2]>=TopPeaksPos[pos];pos2++)
if(value>Low[BottomPeaksPos[pos2]]){value=Low[BottomPeaksPos[pos2]];posminmax=pos2;}
if(posminmax>-1)if(TopPeaksPos[pos1]-TopPeaksPos[pos]>BetweenPeaks)if(CheckBorders(TopPeaksPos[pos],TopPeaksPos[pos1],BottomPeaksPos[posminmax],
High[TopPeaksPos[pos]],High[TopPeaksPos[pos1]],Low[BottomPeaksPos[posminmax]])==0){// DRAWING
ExtMapBuffer1[0] = (0-TopPeaksPos[pos])*(High[TopPeaksPos[pos1]]-High[TopPeaksPos[pos]])/(TopPeaksPos[pos1]-TopPeaksPos[pos])+High[TopPeaksPos[pos]];
ExtMapBuffer1[TopPeaksPos[pos1]] = High[TopPeaksPos[pos1]];
ExtMapBuffer2[0] = Low[BottomPeaksPos[posminmax]]+(0-BottomPeaksPos[posminmax])*
(High[TopPeaksPos[pos1]]-High[TopPeaksPos[pos]])/(TopPeaksPos[pos1]-TopPeaksPos[pos]);
ExtMapBuffer2[TopPeaksPos[pos1]] = Low[BottomPeaksPos[posminmax]]+(TopPeaksPos[pos1]-BottomPeaksPos[posminmax])*
(High[TopPeaksPos[pos1]]-High[TopPeaksPos[pos]])/(TopPeaksPos[pos1]-TopPeaksPos[pos]);
ExtMapBuffer3[TopPeaksPos[pos]]=High[TopPeaksPos[pos]];ExtMapBuffer3[TopPeaksPos[pos1]]=High[TopPeaksPos[pos1]];
ExtMapBuffer3[BottomPeaksPos[posminmax]]=Low[BottomPeaksPos[posminmax]];
return (0);
}// DRAWING
}// SECOND POINT SEEK
}else {// BOTTOM NEARLY
for(pos1=pos;pos1<BottomPeaksIndex;pos1++){// SECOND POINT SEEK
value=High[TopPeaksPos[pos]]-10000.0;posminmax=-1;
for(pos2=pos;TopPeaksPos[pos2]<=BottomPeaksPos[pos1] && TopPeaksPos[pos2]>=BottomPeaksPos[pos];pos2++)
if(value<High[TopPeaksPos[pos2]]){value=High[TopPeaksPos[pos2]];posminmax=pos2;}
if(posminmax>-1)if(BottomPeaksPos[pos1]-BottomPeaksPos[pos]>BetweenPeaks)if(CheckBorders(BottomPeaksPos[pos],BottomPeaksPos[pos1],TopPeaksPos[posminmax],
Low[BottomPeaksPos[pos]],Low[BottomPeaksPos[pos1]],High[TopPeaksPos[posminmax]])==0){// DRAWING
ExtMapBuffer1[0] = (0-BottomPeaksPos[pos])*(Low[BottomPeaksPos[pos1]]-Low[BottomPeaksPos[pos]])/(BottomPeaksPos[pos1]-BottomPeaksPos[pos])+Low[BottomPeaksPos[pos]];
ExtMapBuffer1[BottomPeaksPos[pos1]] = Low[BottomPeaksPos[pos1]];
ExtMapBuffer2[0] = High[TopPeaksPos[posminmax]]+(0-TopPeaksPos[posminmax])*
(Low[BottomPeaksPos[pos1]]-Low[BottomPeaksPos[pos]])/(BottomPeaksPos[pos1]-BottomPeaksPos[pos]);
ExtMapBuffer2[BottomPeaksPos[pos1]] = High[TopPeaksPos[posminmax]]+(BottomPeaksPos[pos1]-TopPeaksPos[posminmax])*
(Low[BottomPeaksPos[pos1]]-Low[BottomPeaksPos[pos]])/(BottomPeaksPos[pos1]-BottomPeaksPos[pos]);
ExtMapBuffer3[BottomPeaksPos[pos]]=Low[BottomPeaksPos[pos]];ExtMapBuffer3[BottomPeaksPos[pos1]]=Low[BottomPeaksPos[pos1]];
ExtMapBuffer3[TopPeaksPos[posminmax]]=High[TopPeaksPos[posminmax]];
return (0);
}// DRAWING
}// SECOND POINT SEEK
}// BOTTOM NEARLY
}// SEEK LOOP
return(0);
}
//+------------------------------------------------------------------+
Comments