// Downloaded From https://www.WiseStockTrader.com
// code by E.M.Pottasch, Dec 2014
// idea based on:
// http://www.traderji.com/day-trading/49521-thoughts-day-swing-trading-9.html#post540250
// and: http://www.traderji.com/amibroker/96658-afl-help-needed-plot-lines.html
SetBarsRequired(sbrAll,sbrAll);
xx=BarIndex();Lx=LastValue(xx); 
lvb=Min(Lx,Status("lastvisiblebarindex"));
rightStrength=Param("Right Strength (Major Pivot)",5,1,50,1);
leftStrength=Param("Left Strength (Major Pivot)",5,1,50,1);
rightStrength_mini=Param("Right Strength (Mini Pivot)",1,1,50,1);
leftStrength_mini=Param("Left Strength (Mini Pivot)",1,1,50,1);
showUpGap=ParamToggle("Display Up Gap","No|Yes",1);
showDnGap=ParamToggle("Display Dn Gap","No|Yes",1);
minimumGapFactor=Param("Minimum Gap Factor",0.1,0,5,0.01);
atrArrayPeriod=Param("ATR Array Period",10,0,50,1);
tf=Param("Time Frame (Minutes)",5,1,1440,1);tfrm=in1Minute*tf;
chartArea=ParamToggle("Display Area","Visible Chart|Complete Chart",0);
htag=ParamToggle("Signal Handling","Show Basic Signals|System Type Signals",0);

if(chartArea==0)fvb=Status("firstvisiblebarindex");
if(chartArea==1)fvb=0;
GfxSetOverlayMode(1); 
GfxSetCoordsMode(1); 
GfxSetBkMode(1);
	
cntDnGap=valDnGapHi=valDnGapLo=idxDnGapStart=idxDnGapEnd=exitShort=exitShortPrice=0;
cntUpGap=valUpGapHi=valUpGapLo=idxUpGapStart=idxUpGapEnd=exitLong=exitLongPrice=0;

function pkID(rightStrength,leftStrength)
{
	pk=H>Ref(HHV(H,leftStrength),-1) AND H>=Ref(HHV(H,rightStrength),rightStrength);
	return pk;
}
function trID(rightStrength,leftStrength)
{
	tr=L<Ref(LLV(L,leftStrength),-1) AND L<=Ref(LLV(L,rightStrength),rightStrength);
	return tr;
}

TimeFrameSet(tfrm); 
	pk=pkID(rightStrength,leftStrength);
	tr=trID(rightStrength,leftStrength);
	pkh=IIf(pk,H,Null);
	trl=IIf(tr,L,Null);
	atrarray=Ref(ATR(atrArrayPeriod),-1);
TimeFrameRestore();
atrArray=TimeFrameExpand(atrArray,tfrm,expandfirst);
fact=Nz(Max(tfrm/60,Interval()/60)/(Interval()/60));
if(fact==0)fact=1;
Lkbk=Nz(tfrm/Interval());
if(Lkbk>1)
{
	pk=TimeFrameExpand(pk,tfrm,expandFirst);
	pkh=TimeFrameExpand(pkh,tfrm,expandFirst);
	pkhs=IIf(!IsEmpty(pkh),1,0);pkhs=pkhs-Ref(pkhs,-1);
	pk=pk AND H==pkh;
	cond1=Sum(pk,BarsSince(pkhs==1)+1)==1 AND pk;
	pk=pk AND cond1;
	
	tr=TimeFrameExpand(tr,tfrm,expandFirst);	
	trl=TimeFrameExpand(trl,tfrm,expandFirst);
	trls=IIf(!IsEmpty(trl),1,0);trls=trls-Ref(trls,-1);
	tr=tr AND L==trl;
	cond1=Sum(tr,BarsSince(trls==1)+1)==1 AND tr;
	tr=tr AND cond1;
}

pkm=pkID(rightStrength_mini,leftStrength_mini);
trm=trID(rightStrength_mini,leftStrength_mini);

function handleSignals(Buy,BuyPrice,Sell,SellPrice,Short,ShortPrice,Cover,CoverPrice)
{
global BuyAdjusted;
global BuyPriceAdjusted;
global ShortAdjusted;
global ShortPriceAdjusted;
global SellAdjusted;
global SellPriceAdjusted;
global CoverAdjusted;
global CoverPriceAdjusted;
global longTarget;
global shortTarget;

BuyAdjusted=0;
BuyPriceAdjusted=0;
ShortAdjusted=0;
ShortPriceAdjusted=0;
SellAdjusted=0;
SellPriceAdjusted=0;
CoverAdjusted=0;
CoverPriceAdjusted=0;
slip=0;

for(i=fvb;i<lvb;i++) 
{
	if(Buy[i])
	{
		BuyAdjusted[i]=1;
		BuypriceAdjusted[i]=BuyPrice[i]+slip;
		
		for(j=i+1;j<BarCount;j++) 
		{					
			if(Sell[j])
			{
				SellAdjusted[j]=1;
				SellPriceAdjusted[j]=SellPrice[j]-slip;
				i=j;
				break;				
			}
			else if(Short[j])
			{
				SellAdjusted[j]=1;
				SellPriceAdjusted[j]=ShortPrice[j]-slip;
				i=j-1;
				break;				
			}
			else if(j==BarCount-1)
			{
				i=j;
				break;
			}						
		}
	}
	else if(Short[i])
	{
		ShortAdjusted[i]=1;
		ShortPriceAdjusted[i]=ShortPrice[i]-slip;
		
		for(j=i+1;j<BarCount;j++) 
		{					
			if(Cover[j])
			{
				CoverAdjusted[j]=1;
				CoverPriceAdjusted[j]=CoverPrice[j]-slip;
				i=j;
				break;				
			}
			else if(Buy[j])
			{
				CoverAdjusted[j]=1;
				CoverPriceAdjusted[j]=BuyPrice[j]-slip;
				i=j-1;
				break;				
			}
			else if(j==BarCount-1)
			{
				i=j;
				break;
			}										
		}
	}

}

}

pkHigh1=Ref(ValueWhen(pk,H,1),-(rightStrength*fact+fact));
trLow1=Ref(ValueWhen(Tr,L,1),-(rightStrength*fact+fact));

upGap=Cross(C,pkHigh1);
dnGap=Cross(trLow1,C);
pkHigh0=ValueWhen(pkm,H,0);
trLow0=ValueWhen(trm,L,0);
minimumGap=minimumGapFactor*atrArray;
upGap=Cross(C,pkHigh1) AND pkHigh1<trLow0 AND (trLow0-pkHigh1)>minimumGap AND !pk;
dnGap=Cross(trLow1,C) AND trLow1>pkHigh0 AND (trLow1-pkHigh0)>minimumGap AND !tr;

gapBaseUp=ValueWhen(upGap,pkHigh1);
gapBaseDn=ValueWhen(dnGap,trLow1);
gapExtrUp=ValueWhen(upGap,trLow0);
gapExtrDn=ValueWhen(dnGap,pkHigh0);

function drawRectangle(x1,y1,x2,y2,clr,clr1)
{ 
	GfxSelectPen(clr); 
	GfxSelectSolidBrush(clr); 
	GfxPolygon(x1,y1,x2,y1,x2,y2,x1,y2); 
	GfxSelectPen(clr1,3);
	GfxRoundRect(x1,y1,x2,y2,0,0);	
}
function locateUpGapArea()
{
	for(i=fvb;i<lvb;i++) 
	{
		if(upGap[i])
		{
			valUpGapHi[cntUpGap]=gapExtrUp[i];
			valUpGapLo[cntUpGap]=gapBaseUp[i];
			idxUpGapStart[cntUpgap]=i;
			for(j=i+1;j<BarCount;j++)//find end of Up gap area
			{
				if(L[j]<valUpGapLo[cntUpGap] AND L[j-1]>=valUpGapLo[cntUpGap])
				{
					idxUpGapEnd[cntUpgap]=j;
					exitLong[j]=1;
					exitLongPrice[j]=valUpGapLo[cntUpGap];
					break;
				}
				else if(j==(BarCount-1))
				{
					idxUpGapEnd[cntUpgap]=j;
					break;				
				}
			}
			cntUpGap=cntUpGap+1;
		}
	}
}
function locateDnGapArea()
{
	for(i=fvb;i<lvb;i++) 
	{
		if(dnGap[i])
		{
			valDnGapHi[cntDnGap]=gapBaseDn[i];
			valDnGapLo[cntDnGap]=gapExtrDn[i];
			idxDnGapStart[cntDngap]=i;
			for(j=i+1;j<BarCount;j++)//find end of Down gap area
			{
				if(H[j]>valDnGapHi[cntDnGap] AND H[j-1]<=valDnGapHi[cntDnGap])
				{
					idxDnGapEnd[cntDngap]=j;
					exitShort[j]=1;
					exitShortPrice[j]=valDnGapHi[cntDnGap];
					break;
				}
				else if(j==(BarCount-1))
				{
					idxDnGapEnd[cntDngap]=j;
					break;				
				}		
			}
			cntDnGap=cntDnGap+1;
		}
	}
}
function drawUpGapZones()
{
	for(i=0;i<cntUpGap;i++) 
	{
		x1=idxUpGapStart[i];
		y1=valUpGapHi[i];
		x2=idxUpGapEnd[i];
		y2=valUpGapLo[i];
		drawRectangle(x1,y1,x2,y2,ColorRGB(0,255,0),ColorRGB(0,100,0));		
	}
}
function drawDnGapZones()
{
	for(i=0;i<cntDnGap;i++) 
	{
		x1=idxDnGapStart[i];
		y1=valDnGapHi[i];
		x2=idxDnGapEnd[i];
		y2=valDnGapLo[i];
		drawRectangle(x1,y1,x2,y2,ColorRGB(255,153,0),ColorRGB(166,82,0));
	}
}

SetChartBkColor(ColorRGB(0,0,0));SetChartOptions(0,chartShowDates);
SetBarFillColor(IIf(C>O,colorGreen,IIf(C<=O,colorRed,colorLightGrey)));
Plot(C,"Price",IIf(C>O,colorDarkGreen,IIf(C<=O,colorDarkRed,colorLightGrey)),64,null,null,0,0,1);
PlotShapes(shapeCircle*tr,IIf(Lx-ValueWhen(tr,xx)>rightStrength*fact+fact,ColorRGB(0,255,0),colorWhite),0,L,-10);
PlotShapes(shapeCircle*pk,IIf(Lx-ValueWhen(pk,xx)>rightStrength*fact+fact,ColorRGB(255,0,0),colorWhite),0,H,10);
PlotShapes(shapeSmallCircle*trm,IIf(Lx-ValueWhen(tr,xx)>rightStrength_mini,ColorRGB(0,70,0),colorWhite),0,L,-10);
PlotShapes(shapeSmallCircle*pkm,IIf(Lx-ValueWhen(pk,xx)>rightStrength_mini,ColorRGB(70,0,0),colorWhite),0,H,10);

Plot(pkHigh1,"",colorBlue,1,Null,Null,0,0,1);
Plot(trLow1,"",colorRed,1,Null,Null,0,0,1);


if(showDnGap)
{
	locateDnGapArea();
	drawDnGapZones();
}
if(showUpGap)
{
	locateUpGapArea();
	drawUpGapZones();
}

// add basic trading signals
idxDnGap=ValueWhen(dnGap,xx,1);idxMiniPk=ValueWhen(pkm,xx,0);
shiftx=IIf(dnGap,((idxMiniPk-idxDnGap) + rightStrength_mini + 1),0);
shiftx=ValueWhen(dnGap,shiftx,1);
Short=Ref(dnGap,-shiftx);ShortPrice=O;
Cover=exitShort;CoverPrice=exitShortPrice;

idxUpGap=ValueWhen(upGap,xx,1);idxMiniTr=ValueWhen(trm,xx,0);
shiftx=IIf(upGap,((idxMiniTr-idxUpGap) + rightStrength_mini + 1),0);
shiftx=ValueWhen(UpGap,shiftx,1);
Buy=Ref(upGap,-shiftx);BuyPrice=O;
Sell=exitLong;SellPrice=exitLongPrice;

if(htag)
{
	handleSignals(Buy,BuyPrice,Sell,SellPrice,Short,ShortPrice,Cover,CoverPrice);
	Buy=BuyAdjusted;
	BuyPrice=BuyPriceAdjusted;
	Short=ShortAdjusted;
	ShortPrice=ShortPriceAdjusted;
	Sell=SellAdjusted;
	SellPrice=SellPriceAdjusted;
	Cover=CoverAdjusted;
	CoverPrice=CoverPriceAdjusted;
}

if(showUpGap)
{
	PlotShapes(IIf(Buy,shapeUpArrow,shapeNone),colorDarkGreen,0,L,-15);
	PlotShapes(IIf(Buy,shapeSmallCircle,shapeNone),colorWhite,0,BuyPrice,0);
	PlotShapes(IIf(Sell,shapeDownArrow,shapeNone),colorRed,0,H,-15);
	PlotShapes(IIf(Sell,shapeSmallCircle,shapeNone),colorWhite,0,SellPrice,0);
}
if(showDnGap)
{
	PlotShapes(IIf(Short,shapeSmallDownTriangle,shapeNone),colorRed,0,H,IIf(Short AND Sell,-30,-15));
	PlotShapes(IIf(Short,shapeSmallCircle,shapeNone),colorWhite,0,ShortPrice,0);
	PlotShapes(IIf(Cover,shapeSmallUpTriangle,shapeNone),colorDarkGreen,0,L,IIf(Cover AND Buy,-30,-15));
	PlotShapes(IIf(Cover,shapeSmallCircle,shapeNone),colorWhite,0,CoverPrice,0);
}