// Downloaded From https://www.WiseStockTrader.com
// AFL code by E.M.Pottasch
GfxSetZOrder( 0 );
GfxSetCoordsMode( 1 );
x = BarIndex();
Lx = LastValue( x );
fvb = FirstVisibleValue( x );
lvb = LastVisibleValue( x );

perBull = Param( "perBull", 20, 1, 150, 1 );
perBear = Param( "perBear", 20, 1, 150, 1 );
multBull = Param( "multBull", 2, 1, 4, 0.05 );
multBear = Param( "multBear", 2, 1, 4, 0.05 );
trailValueClose = ParamToggle( "Trail value", "High/Low|Close", 0 );
tf = Param( "Time Frame (min)", 5, 1, 1440, 1 );
tfrm = in1Minute * tf;
tog2 = ParamToggle( "Plot Trail", "No|Yes", 0 );
tog3 = ParamToggle( "Plot Valid High/Low", "No|Yes", 0 );
maxNumberOfTrendlines = Param( "Maximum number of Trendlines", 10, 1, 100, 1 );

function vstop_func( trBull, trBear )
{
    if( trailValueClose )
    {
        tvHigh = C;
        tvLow = C;
    }
    else
    {
        tvHigh = H;
        tvLow = L;
    }

    trailArray[0] = C[0];

    for( i = 1; i < BarCount; i++ )
    {
        prev = trailArray[i - 1];

        if( C[i] > prev AND C[i - 1] > prev ) //long continuation
        {
            trailArray[i] = Max( prev, tvHigh[i] - trBull[i] );
        }
        else
            if( C[i] < prev AND C[i - 1] < prev ) //short continuation
            {
                trailArray[i] = Min( prev, tvLow[i] + trBear[i] );
            }
            else
                if( C[i] > prev AND C[i - 1] <= prev ) //long trigger
                {
                    trailArray[i] = tvHigh[i] - trBull[i];
                }
                else
                    if( C[i] < prev AND C[i - 1] >= prev ) //short trigger
                    {
                        trailArray[i] = tvLow[i] + trBear[i];
                    }
    }

    return trailArray;
}

TimeFrameSet( tfrm );
trBull = multBull * ATR( perBull );
trBear = multBear * ATR( perBear );
trailArray = vstop_func( trBull, trBear );
ts = IIf( trailArray > C, trailArray, Null );
tl = IIf( trailArray < C, trailArray, Null );
TimeFrameRestore();
ts = TimeFrameExpand( ts, tfrm, expandlast );
tl = TimeFrameExpand( tl, tfrm, expandlast );
lll = LLV( L, BarsSince( !IsEmpty( tl ) ) );
lll = IIf( ts, lll, Null );
llls = lll;
ttt1 = IIf( ( !IsEmpty( ts ) AND IsEmpty( Ref( ts, 1 ) ) ) OR BarIndex() == BarCount - 1, 1, Null );
ttt = ValueWhen( ttt1, lll, 0 );
ttt = IIf( ts, ttt, Null );
ttt = IIf( ttt1, Ref( ttt, -1 ), ttt );
tr = L == ttt;
lll = Sum( tr, BarsSince( !IsEmpty( tl ) ) );
qqq = ValueWhen( ttt1, lll, 0 );
qqq = IIf( ts, qqq, Null );
qqq = IIf( ttt1, Ref( qqq, -1 ), qqq );
tr = tr AND lll == qqq;
tr = IIf( ( !IsEmpty( ts ) AND IsEmpty( Ref( ts, 1 ) ) AND IsEmpty( Ref( ts, -1 ) ) ), 1, tr ); //exception

hhh = HHV( H, BarsSince( !IsEmpty( ts ) ) );
hhh = IIf( tl, hhh, Null );
hhhs = hhh;
ttt1 = IIf( ( !IsEmpty( tl ) AND IsEmpty( Ref( tl, 1 ) ) ) OR BarIndex() == BarCount - 1, 1, Null );
ttt = ValueWhen( ttt1, hhh, 0 );
ttt = IIf( tl, ttt, Null );
ttt = IIf( ttt1, Ref( ttt, -1 ), ttt );
pk = H == ttt;
hhh = Sum( pk, BarsSince( !IsEmpty( ts ) ) );
sss = ValueWhen( ttt1, hhh, 0 );
sss = IIf( tl, sss, Null );
sss = IIf( ttt1, Ref( sss, -1 ), sss );
pk = pk AND hhh == sss;
pk = IIf( ( !IsEmpty( tl ) AND IsEmpty( Ref( tl, 1 ) ) AND IsEmpty( Ref( tl, -1 ) ) ), 1, pk ); //exception

pkValid = IsEmpty( tl ) AND !IsEmpty( Ref( tl, -1 ) ) AND !IsEmpty( ts ) AND IsEmpty( Ref( ts, -1 ) ); // valid at bar close
trValid = !IsEmpty( tl ) AND IsEmpty( Ref( tl, -1 ) ) AND IsEmpty( ts ) AND !IsEmpty( Ref( ts, -1 ) ); // valid at bar close
pkHigh1 = ValueWhen( pkValid, ValueWhen( pk, H, 1 ), 1 );
trLow1 = ValueWhen( trValid, ValueWhen( tr, L, 1 ), 1 );

for( i = 0; i < 4; i++ )
{
    VarSet( "px" + i, ValueWhen( pk, x, i ) );
    VarSet( "tx" + i, ValueWhen( tr, x, i ) );
    VarSet( "ph" + i, ValueWhen( pk, H, i ) );
    VarSet( "tl" + i, ValueWhen( tr, L, i ) );
}

ll = tr AND tl1 < tl2;
hl = tr AND tl1 > tl2;
hh = pk AND ph1 > ph2;
lh = pk AND ph1 < ph2;
dt = pk AND ph1 == ph2;
db = tr AND tl1 == tl2;

ll_h = IIf( ll, 1, 0 );
hl_h = IIf( hl, 2, 0 );
hh_h = IIf( hh, 3, 0 );
lh_h = IIf( lh, 4, 0 );
dt_h = IIf( dt, 5, 0 );
db_h = IIf( db, 6, 0 );

combi = ll_h + hl_h + lh_h + hh_h;

t0 = ValueWhen( combi, combi, 0 );
t1 = ValueWhen( combi, combi, 1 );
t2 = ValueWhen( combi, combi, 2 );
t3 = ValueWhen( combi, combi, 3 );
t4 = ValueWhen( combi, combi, 4 );

function drawDownTrendline( dntl, Ax, Ay, Bx, By )
{
    cnt = 0;

    for( i = lvb; i > fvb; i-- )
    {
        if( cnt >= maxNumberOfTrendlines ) break;

        if( dntl[i] )
        {
            cnt = cnt + 1;
            x1 = Ax[i];
            y1 = Ay[i];
            x2 = Bx[i];
            y2 = By[i];
            GfxSelectPen( colorred, 1, 0 );

            dnTrend = LineArray( x1, y1, x2, y2, 1 );
            cpt = Cross( C, dnTrend ) AND x > x2;
            tcpt = Cum( cpt );
            tcpt = LastValue( Max( tcpt, 1 ) );
            x3 = LastValue( ValueWhen( cpt, x, tcpt ) );
            y3 = LastValue( ValueWhen( cpt, dnTrend, tcpt ) );

            if( y3 == 0 ) // for not yet complete trendline
            {
                x3 = BarCount - 1;
                y3 = dnTrend[BarCount - 1];
            }

            GfxPolyline( x1, y1, x2, y2, x3, y3 );
        }
    }
}

dntl = pk AND t1 == 4 AND( t3 == 3 OR t3 == 4 );
Ax = ValueWhen( dntl, px2 );
Ay = ValueWhen( dntl, ph2 );
Bx = ValueWhen( dntl, px1 );
By = ValueWhen( dntl, ph1 );

drawDownTrendline( dntl, Ax, Ay, Bx, By );

GraphXSpace = 5;
SetChartBkColor( colorBlack );
SetChartOptions( 1, chartShowDates, chartGridMiddle, 0, 0, 0 );
SetBarFillColor( IIf( C > O, ColorRGB( 0, 75, 0 ), IIf( C <= O, ColorRGB( 75, 0, 0 ), colorLightGrey ) ) );
Plot( C, "", IIf( C > O, ColorRGB( 0, 255, 0 ), IIf( C <= O, ColorRGB( 255, 0, 0 ), colorLightGrey ) ), 64, Null, Null, 0, 0, 1 );

if( tog2 )
{
    Plot( ts, "", colorRed, styleStaircase | styleNoRescale, Null, Null, 0, 0, 2 );
    Plot( llls, "", colorRed, styleDashed | styleNoRescale, Null, Null, 0, 0, 1 );
    Plot( tl, "", colorGreen, styleStaircase | styleNoRescale, Null, Null, 0, 0, 2 );
    Plot( hhhs, "", colorGreen, styleDashed | styleNoRescale, Null, Null, 0, 0, 1 );
}

if( tog3 )
{
    Plot( pkHigh1, "", colorBlue, styleLine | styleNoRescale, Null, Null, 0, 0, 2 );
    Plot( trLow1, "", colorRed, styleLine | styleNoRescale, Null, Null, 0, 0, 2 );
}

PlotShapes( shapeCircle*tr, IIf( ValueWhen( tr, x, 1 ) <= ValueWhen( trValid, x, 0 ), ColorRGB( 0, 255, 0 ), ColorRGB( 255, 255, 255 ) ), 0, L, -10 );
PlotShapes( shapeCircle*pk, IIf( ValueWhen( pk, x, 1 ) <= ValueWhen( pkValid, x, 0 ), ColorRGB( 255, 0, 0 ), ColorRGB( 255, 255, 255 ) ), 0, H, 10 );

function drawPivotLabels()
{
    for( i = lvb; i > fvb; i-- )
    {
        {
            if( ll[i] )
                PlotTextSetFont( "LL | " + L[ i ], "Arial Black", 8, i, L[i], colorGreen, colorDefault, -45 );

            if( hl[i] )
                PlotTextSetFont( "HL | " + L[ i ], "Arial Black", 8, i, L[i], colorGreen, colorDefault, -45 );

            if( db[i] )
                PlotTextSetFont( "DB | " + L[ i ], "Arial Black", 8, i, L[i], colorLightBlue, colorDefault, -45 );

            if( hh[i] )
                PlotTextSetFont( "HH | " + H[ i ], "Arial Black", 8, i, H[i], colorRed, colorDefault, 35 );

            if( lh[i] )
                PlotTextSetFont( "LH | " + H[ i ], "Arial Black", 8, i, H[i], colorRed, colorDefault, 35 );

            if( dt[i] )
                PlotTextSetFont( "DT | " + H[ i ], "Arial Black", 8, i, H[i], colorOrange, colorDefault, 25 );
        }
    }
}

Title = Name() +
        " | " + Now( 2 ) +
        " | " + EncodeColor( colorBlue ) + pkHigh1 + EncodeColor( colorWhite ) +
        " | " + EncodeColor( colorRed ) + trLow1 + EncodeColor( colorWhite ) +
        " | " + EncodeColor( colorgreen ) + tl + EncodeColor( colorWhite ) +
        " | " + EncodeColor( colorred ) + ts + EncodeColor( colorWhite );

drawPivotLabels();