_2523MTF_shi_channel_1
Download scriptThis script is designed as a technical analysis tool that automatically identifies and visualizes price trends using a "channel" logic. Instead of just looking at the current price, it analyzes historical price movements to construct a geometric corridor on your chart.
Core Logic & Functionality
1. Automatic Structure Identification The script begins by scanning past market data to find significant "fractals"—essentially the local peaks (highs) and valleys (lows) of the price action. It uses specific settings based on the timeframe you are viewing to determine how far back it should look to confirm these points. Once it identifies a notable high and a notable low, it establishes the foundation for its channel.
2. Channel Construction Using the identified peaks and valleys, the script calculates the "slope" of the market. It draws three primary visual components:
- Upper Boundary: Represents the ceiling of the current price movement.
- Lower Boundary: Represents the floor of the current price movement.
- Median Line: A dotted center line that represents the equilibrium of the channel, helping to identify the "fair value" of the asset.
3. Trend & Momentum Analysis The script doesn't just draw lines; it calculates the mathematical relationship between them:
- Directional Slope: It determines if the price is trending upwards or downwards by calculating the step difference between points.
- Volatility Filtering: It includes a "flatness" check. By comparing the width of the channel to current market volatility (using an ATR calculation), the script can distinguish between a strong, trending market and a sideways, "choppy" market.
4. Dynamic Labeling & Signals Based on the interaction between the current price, the channel boundaries, and the calculated volatility, the script provides text labels directly on the chart:
- Buy/Sell Signals: When the market shows clear momentum, it identifies potential entry points based on whether the price is interacting with the boundaries.
- "Take" Labels: In scenarios where the market is moving but lacks enough strength to be a definitive trend change, it may label positions as "Take," suggesting a different level of conviction compared to a standard Buy or Sell.
User Experience Summary
For a trader, this script simplifies complex price action into a clear visual corridor. It automatically updates the boundaries as new highs and lows are formed, providing a real-time look at the market's "path of least resistance." By distinguishing between trending markets and flat markets, it helps users avoid trading in non-directional environments where channel breakouts are less reliable.
/*-----------------------------+
| |
| Shared by www.Aptrafx.com |
| |
+------------------------------*/
//+------------------------------------------------------------------+
//| SHI_Channel.mq4 |
//|Alex_Bugalter |
//+------------------------------------------------------------------+
#property copyright "Alex_Bugalter"
#property link "Alex_Bugalter@treide.ru"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red
double ExtMapBuffer1[];
//---- input parameters
extern int TimeFrame=60;
extern int AllBars=240;
extern int BarsForFract=0;
extern double flatCriteria=0.25;
extern color collor=Lime;
int CurrentBar=0;
double Step=0;
int B1=-1,B2=-1;
int UpDown=0;
double P1=0,P2=0,PP=0;
int i=0,AB=300,BFF=0;
int ishift=0;
double iprice=0;
datetime T1,T2;
int trend,flat;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
//---- indicators
SetIndexStyle(0,DRAW_ARROW);
SetIndexArrow(0,164);
SetIndexBuffer(0,ExtMapBuffer1);
SetIndexEmptyValue(0,0.0);
//----
return(0);
}
//+------------------------------------------------------------------+
//| Custor indicator deinitialization function |
//+------------------------------------------------------------------+
int deinit()
{
//----
//----
return(0);
}
void DelObj()
{
ObjectDelete("TL1"+TimeFrame);
ObjectDelete("TL2"+TimeFrame);
ObjectDelete("MIDL"+TimeFrame);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int start()
{
int i,limit,y=0;
int counted_bars=IndicatorCounted();
limit=Bars-counted_bars;
int X = (Ask-P1);
int X2 = (Bid-P2);
//----
if ((AllBars==0) || (Bars<AllBars)) AB=Bars; else AB=AllBars; //AB-êîëè÷åñòâî îáñ÷èòûâàåìûõ áàðîâ
// string TimeFrame;
if (BarsForFract>0)
BFF=BarsForFract;
else
{
switch (TimeFrame)
{
case 1: BFF=12; break;
case 5: BFF=48; break;
case 15: BFF=24; break;
case 30: BFF=24; break;
case 60: BFF=12; break;
case 240: BFF=15; break;
case 1440: BFF=10; break;
case 10080: BFF=6; break;
default: DelObj(); return(-1); break;
X = P1;
}
}
CurrentBar=2; //ñ÷èòàåì ñ òðåòüåãî áàðà, ÷òîáû ôðàêòàë "çàêðåïèëñÿ
B1=y-1; B2=y-1; UpDown=0;
while(((B1==-1) || (B2==-1)) && (CurrentBar<AB))
{
//UpDown=1 çíà÷èò ïåðâûé ôðàêòàë íàéäåí ñâåðõó, UpDown=-1 çíà÷èò ïåðâûé ôðàêòàë
//íàéäåí ñíèçó, UpDown=0 çíà÷èò ôðàêòàë åù¸ íå íàéäåí.
//Â1 è Â2 - íîìåðà áàðîâ ñ ôðàêòàëàìè, ÷åðåç íèõ ñòðîèì îïîðíóþ ëèíèþ.
//Ð1 è Ð2 - ñîîòâåòñòâåííî öåíû ÷åðåç êîòîðûå áóäåì ëèíèþ ïðîâîäèòü
if((UpDown<1) && (CurrentBar==Lowest(Symbol(),TimeFrame,MODE_LOW,BFF*2+1,CurrentBar-BFF)))
{
if(UpDown==0)
{
UpDown=-1; B1=CurrentBar; P1=iLow(Symbol(),TimeFrame,B1);
}
else
{
B2=CurrentBar; P2=iLow(Symbol(),TimeFrame,B2);
}
}
if((UpDown>-1) && (CurrentBar==Highest(Symbol(),TimeFrame,MODE_HIGH,BFF*2+1,CurrentBar-BFF)))
{
if(UpDown==0)
{
UpDown=1; B1=CurrentBar; P1=iHigh(Symbol(),TimeFrame,B1);
}
else
{
B2=CurrentBar; P2=iHigh(Symbol(),TimeFrame,B2);
}
}
CurrentBar++;
}
if((B1==-1) || (B2==-1))
{
DelObj();
return(-1);
} // Çíà÷èò íå íàøëè ôðàêòàëîâ ñðåäè 300 áàðîâ
Step=(P2-P1)/(B2-B1);//Âû÷èñëèëè øàã, åñëè îí ïîëîæèòåëüíûé, òî êàíàë íèñõîäÿùèé
P1=P1-B1*Step; B1=0;//ïåðåñòàâëÿåì öåíó è ïåðâûé áàð ê íóëþ
//À òåïåðü îïîðíóþ òî÷êó ïðîòèâîïîëîæíîé ëèíèè êàíàëà.
ishift=0; iprice=0;
if(UpDown==1)
{
PP=iLow(Symbol(),TimeFrame,2)-2*Step;
for(i=3;i<=B2;i++)
{
if(iLow(Symbol(),TimeFrame,i)<PP+Step*i)
{
PP=iLow(Symbol(),TimeFrame,i)-i*Step;
}
}
if(iLow(Symbol(),TimeFrame,0)<PP)
{
ishift=0;
iprice=PP;
}
if(iLow(Symbol(),TimeFrame,1)<PP+Step)
{
ishift=1;
iprice=PP+Step;
}
if(iHigh(Symbol(),TimeFrame,0)>P1)
{
ishift=0;
iprice=P1;
}
if(iHigh(Symbol(),TimeFrame,1)>P1+Step)
{
ishift=1;
iprice=P1+Step;
}
}
else
{
PP=iHigh(Symbol(),TimeFrame,2)-2*Step;
for(i=3;i<=B2;i++)
{
if(iHigh(Symbol(),TimeFrame,i)>PP+Step*i)
{
PP=iHigh(Symbol(),TimeFrame,i)-i*Step;
}
}
if(iLow(Symbol(),TimeFrame,0)<P1)
{
ishift=0;
iprice=P1;
}
if(iLow(Symbol(),TimeFrame,1)<P1+Step)
{
ishift=1;
iprice=P1+Step;
}
if(iHigh(Symbol(),TimeFrame,0)>PP)
{
ishift=0;
iprice=PP;
}
if(iHigh(Symbol(),TimeFrame,1)>PP+Step)
{
ishift=1;
iprice=PP+Step;
}
}
//Òåïåðü ïåðåñòàâèì êîíå÷íóþ öåíó è áàð íà ÀÂ, ÷òîáû ëèíèè êàíàëà ðèñîâàëèñü ïîäëèííåå
P2=P1+AB*Step;
T1=Time[iBarShift(Symbol(),0,iTime(Symbol(),TimeFrame,B1))];
T2=Time[iBarShift(Symbol(),0,iTime(Symbol(),TimeFrame,AB))];
//Print("P1=",P1," P2=",P2);
//Åñëè íå áûëî ïåðåñå÷åíèÿ êàíàëà, òî 0, èíà÷å ñòàâèì ïñèñó.
if(iprice!=0) ExtMapBuffer1[ishift]=iprice;
//DelObj();
if (Step>0) trend=-1; else trend=1;
if (MathAbs(Step*20)>=2*iATR(Symbol(),TimeFrame,40,0)*flatCriteria) flat=0; else flat=1;
if (ObjectFind("TL1"+TimeFrame)==-1)
{
ObjectCreate("TL1"+TimeFrame,OBJ_TREND,0,T2,PP+Step*AB,T1,PP);
ObjectSet("TL1"+TimeFrame,OBJPROP_COLOR,collor);
ObjectSet("TL1"+TimeFrame,OBJPROP_WIDTH,2);
}
else
{
ObjectSet("TL1"+TimeFrame, OBJPROP_TIME1,T2);
ObjectSet("TL1"+TimeFrame, OBJPROP_PRICE1,PP+Step*AB);
ObjectSet("TL1"+TimeFrame, OBJPROP_TIME2,T1);
ObjectSet("TL1"+TimeFrame, OBJPROP_PRICE2,PP);
ObjectSet("TL1"+TimeFrame,OBJPROP_COLOR,collor);
ObjectSet("TL1"+TimeFrame,OBJPROP_WIDTH,2);
}
/*
ObjectSet("TL1",OBJPROP_COLOR,ForestGreen);
ObjectSet("TL1",OBJPROP_WIDTH,2);
ObjectSet("TL1",OBJPROP_STYLE,STYLE_SOLID);
*/
if (ObjectFind("TL2"+TimeFrame)==-1)
{
ObjectCreate("TL2"+TimeFrame,OBJ_TREND,0,T2,P2,T1,P1);
ObjectSet("TL2"+TimeFrame,OBJPROP_COLOR,collor);
ObjectSet("TL2"+TimeFrame,OBJPROP_WIDTH,2);
}
else
{
ObjectSet("TL2"+TimeFrame, OBJPROP_TIME1,T2);
ObjectSet("TL2"+TimeFrame, OBJPROP_PRICE1,P2);
ObjectSet("TL2"+TimeFrame, OBJPROP_TIME2,T1);
ObjectSet("TL2"+TimeFrame, OBJPROP_PRICE2,P1);
ObjectSet("TL2"+TimeFrame,OBJPROP_COLOR,collor);
ObjectSet("TL2"+TimeFrame,OBJPROP_WIDTH,2);
}
/*
ObjectSet("TL2",OBJPROP_COLOR,ForestGreen);
ObjectSet("TL2",OBJPROP_WIDTH,2);
ObjectSet("TL2",OBJPROP_STYLE,STYLE_SOLID);
*/
if (ObjectFind("MIDL"+TimeFrame)==-1)
{
ObjectCreate("MIDL"+TimeFrame,OBJ_TREND,0,T2,(P2+PP+Step*AB)/2,T1,(P1+PP)/2);
ObjectSet("MIDL"+TimeFrame,OBJPROP_COLOR,collor);
ObjectSet("MIDL"+TimeFrame,OBJPROP_WIDTH,1);
ObjectSet("MIDL"+TimeFrame,OBJPROP_STYLE,STYLE_DOT);
}
else
{
ObjectSet("MIDL"+TimeFrame, OBJPROP_TIME1,T2);
ObjectSet("MIDL"+TimeFrame, OBJPROP_PRICE1,(P2+PP+Step*AB)/2);
ObjectSet("MIDL"+TimeFrame, OBJPROP_TIME2,T1);
ObjectSet("MIDL"+TimeFrame, OBJPROP_PRICE2,(P1+PP)/2);
ObjectSet("MIDL"+TimeFrame,OBJPROP_WIDTH,1);
ObjectSet("MIDL"+TimeFrame,OBJPROP_STYLE,STYLE_DOT);
ObjectSet("MIDL"+TimeFrame,OBJPROP_COLOR,collor);
}
/*
ObjectSet("MIDL",OBJPROP_COLOR,ForestGreen);
ObjectSet("MIDL",OBJPROP_WIDTH,1);
ObjectSet("MIDL",OBJPROP_STYLE,STYLE_DOT);
*/
if (flat==1)
{
//Print("flat=1");
if(PP+Step*AB>P2)
{
ObjectSetText("TL1"+TimeFrame,"Sell");
ObjectSetText("TL2"+TimeFrame,"Buy");
}
else
{
ObjectSetText("TL2"+TimeFrame,"Sell");
ObjectSetText("TL1"+TimeFrame,"Buy");
}
}
else
{
//Print("flat=0");
if((PP+Step*AB>P2)&&(trend==-1))
{
ObjectSetText("TL1"+TimeFrame,"Sell");
ObjectSetText("TL2"+TimeFrame,"Take");
}
if((PP+Step*AB>P2)&&(trend==1))
{
ObjectSetText("TL1"+TimeFrame,"Take");
ObjectSetText("TL2"+TimeFrame,"Buy");
}
if((PP+Step*AB<P2)&&(trend==-1))
{
ObjectSetText("TL2"+TimeFrame,"Sell");
ObjectSetText("TL1"+TimeFrame,"Take");
}
if((PP+Step*AB<P2)&&(trend==1))
{
ObjectSetText("TL2"+TimeFrame,"Take");
ObjectSetText("TL1"+TimeFrame,"Buy");
}
}
//} //----
// Comment("Âåðõ êàíàëà = ",PP,"\n","Ñåðåäèíà = ",(P1+PP)/2,"\n","Íèç êàíàëà = ",P1,"\n","Øèðèíà = ",(PP-P1),"\n","Êàñàíèå Âåðõà = ",-(PP-Bid)," ïèïñîâ","\n","Êàñàíèå Íèçà = ",(P1-Ask)," ïèïñîâ");
return(0);
}
//+------------------------------------------------------------------+
Comments