'Dynamic' Shi Channel

 

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;
}
}

 

Please let me know if you get it working. Mine in Meta 4 is not working very well either.

 

Does anyone have a channel indicator (similar to SHI channels) that uses 2 buffers to draw the channel lines?

Please post if you have one, thanks