![MQL5 - Language of trade strategies built-in the MetaTrader 5 client terminal](https://c.mql5.com/i/registerlandings/logo-2.png)
You are missing trading opportunities:
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
Registration
Log in
You agree to website policy and terms of use
If you do not have an account, please register
Hello,
I am trying to rewrite the shi_channel_talking.mq4 indicator which most of you will be familiar with. The original suffers from the redraw problem, repainting the past, making it look different from how it actually was at the time. Therefore, the goal is to create a 'dynamic channel' which draws the channel high/low at each tick based on only the information available at that time. The following is the code as produced thus far, however the lines drawn by the indicator appear to be erratic and not accurately portraying the channels.
If anyone can help fix this, I think the finished indicator could be extremely useful to traders.
Thank you.
My apologies if the code does not copy/paste neatly.
----------------------------------------
//+------------------------------------------------------------------+
//| Dynamic Channel.mq4 |
//| |
//+------------------------------------------------------------------+
#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 Yellow
#property indicator_color2 Yellow
extern int TIME_FRAME = PERIOD_H4;
// Channel Lines
double TL1, TL2;
// Buffers
double ExtUpperBuffer[];
double ExtLowerBuffer[];
//+------------------------------------------------------------------+
//| INITIALISATION FUNCTION |
//+------------------------------------------------------------------+
int init()
{
IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS));
IndicatorShortName("Dynamic Channel");
// drawing settings
SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,1);
SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,1);
// buffers
SetIndexBuffer(0,ExtUpperBuffer);
SetIndexBuffer(1,ExtLowerBuffer);
// labels
SetIndexLabel(0,"TL1");
SetIndexLabel(1,"TL2");
// start points
SetIndexDrawBegin(0,240);
SetIndexDrawBegin(1,240);
// finished
return(0);
}
//+------------------------------------------------------------------+
//| MAIN FUNCTION |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
// main loop
int i = Bars-counted_bars-1;
while(i>=0)
{
Channel(TIME_FRAME,i);
ExtLowerBuffer = TL2;
ExtUpperBuffer = TL1;
i--;
}
// Finished
return(0);
}
//--------------------------------------------------
// CHANNEL
//--------------------------------------------------
void Channel(int TimeFrame, int p)
{
// Channel Variables
double Step=0, P1=0, P2=0, PP=0;
int CurrentBar=p+2;
int B1=-1, B2=-1, UpDown=0, i=0, AB=p+240;
datetime T1, T2;
int BFF;
switch (TimeFrame)
{
case PERIOD_M1: BFF=12; break; // minute chart
case PERIOD_M5: BFF=48; break; // five minute chart
case PERIOD_M15: BFF=24; break; // fifteen minute chart
case PERIOD_M30: BFF=24; break; // half hourly chart
case PERIOD_H1: BFF=12; break; // hourly chart
case PERIOD_H4: BFF=15; break; // 4 hourly chart
case PERIOD_D1: BFF=10; break; // daily chart
case PERIOD_W1: BFF=6; break; // weekly chart
default: return(-1); break; // error
}
while(((B1==-1) || (B2==-1)) && (CurrentBar<AB))
{
if((UpDown<1) && (CurrentBar==Lowest(NULL,TimeFrame,MODE_LOW,BFF*2+ 1,CurrentBar-BFF)))
{
if(UpDown==0) { UpDown=-1; B1=CurrentBar; P1=iLow(NULL,TimeFrame,B1); }
else { B2=CurrentBar; P2=iLow(NULL,TimeFrame,B2); }
}
if((UpDown>-1) && (CurrentBar==Highest(NULL,TimeFrame,MODE_HIGH,BFF* 2+1,CurrentBar-BFF)))
{
if(UpDown==0) { UpDown=1; B1=CurrentBar; P1=iHigh(NULL,TimeFrame,B1); }
else { B2=CurrentBar; P2=iHigh(NULL,TimeFrame,B2); }
}
CurrentBar++;
}
if((B1==-1) || (B2==-1)) {return(-1);} // error
Step=(P2-P1)/(B2-B1);
P1=P1-B1*Step; B1=p;
if(UpDown==1)
{
PP=iLow(NULL,TimeFrame,p+2)-2*Step;
for(i=p+3;i<=B2;i++)
{
if(iLow(NULL,TimeFrame,i)<PP+Step*i) { PP=iLow(NULL,TimeFrame,i)-i*Step; }
}
}
else
{
PP=iHigh(NULL,TimeFrame,p+2)-2*Step;
for(i=p+3;i<=B2;i++)
{
if(iHigh(NULL,TimeFrame,i)>PP+Step*i) { PP=iHigh(NULL,TimeFrame,i)-i*Step;}
}
}
P2=P1+AB*Step;
T1=iTime(NULL,TimeFrame,B1);
T2=iTime(NULL,TimeFrame,AB);
// Channel width
double ChannelWidth=MathAbs(PP - P1)/Point;
// Generic Time
int x1 = T2;
int x2 = T1;
// Upper Channel
double TL2_y1 = P2;
double TL2_y2 = P1;
// Lower Channel
double TL1_y1 = PP+Step*AB;
double TL1_y2 = PP;
// Calculate gradient
double m = (TL1_y2 - TL1_y1) / (x2 - x1);
// Calculate constant for the equation of the upper line
double c_TL1 = TL1_y2 - (m*x2);
// Calculate constant for the equation of the lower line
double c_TL2 = TL2_y2 - (m*x2);
// Calculate channel prices for current tick
TL2 = (m*iTime(NULL,TimeFrame,p)) + c_TL2;
TL1 = (m*iTime(NULL,TimeFrame,p)) + c_TL1;
// Ensure TL1 is upper channel
if(TL1 < TL2)
{
double temp = TL1;
TL1 = TL2;
TL2 = temp;
}
}