Stock Portfolio Organizer

The ultimate porfolio management solution.

Shares, Margin, CFD's, Futures and Forex
EOD and Realtime
Dividends and Trust Distributions
And Much More ....
For Portfolio Manager Click Here

WiseTrader Toolbox

#1 Selling Amibroker Plugin featuring:

Advanced Adaptive Indicators
Advanced Pattern Exploration
Neural Networks
And Much More ....
Find Out More Here

harmonics plus zones for Amibroker (AFL)

Copy & Paste Friendly
/* HARMONIC PATTERN DETECTION using ATR type Peaks and Troughs

Automatic Detection of Harmonic Patterns - Gartley, Bat, Butterfly and Crab.
Original code by joy.edakad@gmail.com, see:
http://www.inditraders.com/amibroker/1934-afl-harmonic-patterns.html
file: Harmonic1.1.afl (2009)

Modernized by E.M.Pottasch
- Using ATR based pivots instead of fractal based
- Improved visualisation of the patterns.
- Nomenclature of variables, constants and arrays, adjusted
	following code from David Keleher.
- uncompleted pivots given white color
- multiple issues of the original code corrected for
- added potential reversal zones

The original code was based on "fractal type pivots", this code uses 
"ATR type pivots". This code also includes a timeframe factor. To fully 
understand how to interpret a pattern use the Amibroker playback utility 
and see how the patterns develop. 

The potential reversal zones are based on the parameter constraints for 
each pattern. 1 pattern may transform into another pattern. Only the 
last pattern is shown, however the reversal zones for subsequent patterns 
are shown.  E.M.Pottasch (Jan 2017). */

Version( 6.0 );
GfxSetZOrder( -5 );
GfxSetCoordsMode( 1 ); 

BullBat4 = BullButterfly4 = BullCrab4 = BullGartley4 = 0;
BullBat = BullButterfly = BullCrab = BullGartley = 0;
BearBat4 = BearButterfly4 = BearCrab4 = BearGartley4 = 0;
BearBat = BearButterfly = BearCrab = BearGartley = 0;
pk = tr = pkn = trn = 0;

bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );

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

_SECTION_BEGIN( "Patterns" );
perBull = Param( "Bullish ATR Period", 20, 1, 150, 1 );
perBear = Param( "Bearish ATR Period", 20, 1, 150, 1 );
multBull = Param( "Bullish ATR Multiple", 2, 1, 4, 0.05 );
multBear = Param( "Bearish ATR Multiple", 2, 1, 4, 0.05 );
trailValueClose = ParamToggle( "Trail value", "High/Low|Close", 1 );
//tfrm = in1Minute * Param( "Time Frame (min)", 5, 1, 1440 * 10, 1 ); // 1440 minutes is 1 day
tfrm = in1Minute * Interval() / 60 * Param( "Chart Time Frame Factor", 1, 1, 10, 1 ); // factor 1 uses timeframe of chart
showATRPivots = ParamToggle( "Show ATR Pivots", "Off|On", 0 );
showLabels = ParamToggle( "Show ATR Pivot Labels", "Off|On", 0 );
bu = ParamToggle( "Show Bullish Pattern", "Off|On", 1 );
be = ParamToggle( "Show Bearish Pattern", "Off|On", 1 );
nBull = Param( "Max Number of Bullish Patterns", 10, 0, 100, 1 );
nBear = Param( "Max Number of Bearish Patterns", 10, 0, 100, 1 );
dBat = ParamToggle( "Draw Bat", "Off|On", 1 );
dBut = ParamToggle( "Draw Buterfly", "Off|On", 1 );
dCrab = ParamToggle( "Draw Crab", "Off|On", 1 );
dGart = ParamToggle( "Draw Gartley", "Off|On", 1 );
showPatternDevelopmentPoints = ParamToggle( "Show Points of Pattern Development", "Off|On", 1 );
showPatternLabels = ParamToggle( "Show Pattern Labels", "Off|On", 1 );
showPatternName = ParamToggle( "Show Pattern Name", "Off|On", 1 );
showReversalZone = ParamToggle( "Show Reversal Zone", "Off|On", 1 );
colorContrastFactor = Param( "Color Contrast Factor", 10, 2, 100, 2 );
_SECTION_END();

_SECTION_BEGIN( "Gartley" );
GarABXAmin = Param( "Swing B Min.(XA)", 0.55, 0.3, 1, 0.01 );
GarABXAmax = Param( "Swing B Max.(XA)", 0.72, 0.4, 1, 0.01 );
GarBCABmin = Param( "Swing C Min.(AB)", 0.38, 0.3, 1.27, 0.01 );
GarBCABmax = Param( "Swing C Max.(AB)", 1.0, 0.4, 1.27, 0.01 );
GarCDXAmin = Param( "Swing D Min.(XA)", 0.55, 0.3, 1, 0.01 );
GarCDXAmax = Param( "Swing D Max.(XA)", 1.0, 0.4, 1.0, 0.01 );
_SECTION_END();

_SECTION_BEGIN( "Bat" );
BatABXAmin = Param( "Swing AB Min.(XA)", 0.38, 0.3, 1, 0.01 );
BatABXAmax = Param( "Swing AB Max.(XA)", 0.55, 0.4, 1, 0.01 );
BatBCABmin = Param( "Swing BC Min.(AB)", 0.38, 0.3, 1.62, 0.01 );
BatBCABmax = Param( "Swing BC Max.(AB)", 1.27, 0.4, 1.62, 0.01 );
BatCDXAmin = Param( "Swing CD Min.(XA)", 0.5, 0.3, 1, 0.01 );
BatCDXAmax = Param( "Swing CD Max.(XA)", 1.0, 0.4, 1.0, 0.01 );
_SECTION_END();

_SECTION_BEGIN( "Butterfly" );
ButABXAmin = Param( "Swing B Min.(XA)", 0.55, 0.3, 1, 0.01 );
ButABXAmax = Param( "Swing B Max.(XA)", 0.9, 0.4, 1, 0.01 );
ButBCABmin = Param( "Swing C Min.(AB)", 0.38, 0.3, 1.62, 0.01 );
ButBCABmax = Param( "Swing C Max.(AB)", 1.27, 0.4, 1.62, 0.01 );
ButCDXAmin = Param( "Swing D Min.(XA)", 1, 1, 1.8, 0.01 );
ButCDXAmax = Param( "Swing D Max.(XA)", 1.38, 1, 1.8, 0.01 );
_SECTION_END();

_SECTION_BEGIN( "Crab" );
CraABXAmin = Param( "Swing B Min.(XA)", 0.38, 0.3, 1, 0.01 );
CraABXAmax = Param( "Swing B Max.(XA)", 0.65, 0.4, 1, 0.01 );
CraBCABmin = Param( "Swing C Min.(AB", 0.38, 0.3, 1.62, 0.01 );
CraBCABmax = Param( "Swing C Max.(AB)", 1.270, 0.4, 1.62, 0.01 );
CraCDXAmin = Param( "Swing D Min.(XA)", 1.25, 1, 1.8, 0.01 );
CraCDXAmax = Param( "Swing D Max.(XA)", 1.8, 1, 2, 0.01 );
_SECTION_END();

function ATRtrail_func()
{
    // Trail code largely from:
    // http://traders.com/Documentation/FEEDbk_docs/2009/06/TradersTips.html
    if( trailValueClose )
    {
        tvHigh = C;
        tvLow = C;
    }
    else
    {
        tvHigh = H;
        tvLow = L;
    }

    sup = tvHigh - multBull * ATR( perBull );
    res = tvLow + multBear * ATR( perBear );

    trailARRAY = Null;
    trailstop = 0;

    for( i = 1; i < BarCount; i++ )
    {
        if( C[ i ] > trailstop AND C[ i - 1 ] > trailstop )
            trailstop = Max( trailstop, sup[ i ] );
        else
            if( C[ i ] < trailstop AND C[ i - 1 ] < trailstop )
                trailstop = Min( trailstop, res[ i ] );
            else
                trailstop = IIf( C[ i ] > trailstop, sup[ i ], res[ i ] );

        trailARRAY[ i ] = trailstop;
    }

    return trailARRAY;
}

TimeFrameSet( tfrm );
trBull = multBull * ATR( perBull );
trBear = multBear * ATR( perBear );
trailArray = ATRtrail_func();
ts = IIf( trailArray > C, trailArray, Null ); // dntrend
tl = IIf( trailArray < C, trailArray, Null ); // uptrend
TimeFrameRestore();

ts = TimeFrameExpand( ts, tfrm, expandlast );
tl = TimeFrameExpand( tl, tfrm, expandlast );

lll = LLV( L, BarsSince( !IsEmpty( tl ) ) );
lll = IIf( ts, lll, Null );
trn = ts AND L == lll;

hhh = HHV( H, BarsSince( !IsEmpty( ts ) ) );
hhh = IIf( tl, hhh, Null );
pkn = tl AND H == hhh;

tr = ExRem( Reverse( trn ), Reverse( pkn ) );
pk = ExRem( Reverse( pkn ), Reverse( trn ) );

tr = Reverse( tr );
pk = Reverse( pk );

for( i = 0; i < 3; i++ )
{
    VarSet( "px" + i, ValueWhen( pk, bi, i ) );
    VarSet( "tx" + i, ValueWhen( tr, bi, 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;

if( showATRPivots )
{
    PlotShapes( shapeSmallCircle * tr, IIf( tx1 < px0, ColorRGB( 0, 0, 255 ), colorWhite ), 0, L, -10 );
    PlotShapes( shapeSmallCircle * pk, IIf( px1 < tx0, ColorRGB( 255, 0, 0 ), colorWhite ), 0, H, 10 );
}

// +++ Bullish Patterns
PTvalid = ( px1 > tx1 AND tx1 > px2 AND px2 > tx2 ) AND pk;

if( dGart AND bu )
{
    BullGartley4 = PTvalid AND( ph2 - tl1 ) / ( ph2 - tl2 ) > GarABXAmin AND( ph2 - tl1 ) / ( ph2 - tl2 ) < GarABXAmax
                   AND( ph1 - tl1 ) / ( ph2 - tl1 ) > GarBCABMin AND( ph1 - tl1 ) / ( ph2 - tl1 ) < GarBCABMax;
    BullGartley = IIf( Nz( LowestSince( BullGartley4, L ) ) < Nz( ValueWhen( BullGartley4, ph2 ) ) - ( Nz( ValueWhen( BullGartley4, ph2 ) ) - Nz( ValueWhen( BullGartley4, tl2 ) ) ) * GarCDXAmin AND
                       Nz( LowestSince( bullGartley4, L ) ) > Nz( ValueWhen( BullGartley4, ph2 ) ) - ( Nz( ValueWhen( BullGartley4, ph2 ) ) - Nz( ValueWhen( BullGartley4, tl2 ) ) ) * GarCDXAmax AND
                       Nz( HighestSince( BullGartley4, H ) ) <= Nz( ValueWhen( BullGartley4, ph1 ) ) AND
                       Nz( LowestSince( BullGartley4, L ) ) < Nz( ValueWhen( BullGartley4, tl1 ) ) AND
                       Nz( trn ) AND
                       Nz( LowestSince( bullGartley4, L ) ) == L, True, False );
}

if( dBat AND bu )
{
    BullBat4 = PTvalid AND( ph2 - tl1 ) / ( ph2 - tl2 ) > BatABXAmin AND( ph2 - tl1 ) / ( ph2 - tl2 ) < BatABXAmax
               AND( ph1 - tl1 ) / ( ph2 - tl1 ) > BatBCABMin AND( ph1 - tl1 ) / ( ph2 - tl1 ) < BatBCABMax;
    BullBat = IIf( Nz( LowestSince( BullBat4, L ) ) < Nz( ValueWhen( BullBat4, ph2 ) ) - ( Nz( ValueWhen( BullBat4, ph2 ) ) - Nz( ValueWhen( BullBat4, tl2 ) ) ) * BatCDXAmin AND
                   Nz( LowestSince( BullBat4, L ) ) > Nz( ValueWhen( BullBat4, ph2 ) ) - ( Nz( ValueWhen( BullBat4, ph2 ) ) - Nz( ValueWhen( BullBat4, tl2 ) ) ) * BatCDXAmax AND
                   Nz( HighestSince( BullBat4, H ) ) <= Nz( ValueWhen( BullBat4, ph1 ) ) AND
                   Nz( LowestSince( BullBat4, L ) ) < Nz( ValueWhen( BullBat4, tl1 ) ) AND
                   Nz( trn ) AND
                   Nz( LowestSince( BullBat4, L ) ) == L, True, False );
}

if( dBut AND bu )
{
    BullButterfly4 = PTvalid AND( ph2 - tl1 ) / ( ph2 - tl2 ) > ButABXAmin AND( ph2 - tl1 ) / ( ph2 - tl2 ) < ButABXAMax
                     AND( ph1 - tl1 ) / ( ph2 - tl1 ) > ButBCABmin AND( ph1 - tl1 ) / ( ph2 - tl1 ) < ButBCABmax;
    BullButterfly = IIf( Nz( LowestSince( BullButterfly4, L ) ) < Nz( ValueWhen( BullButterfly4, ph2 ) ) - ( Nz( ValueWhen( BullButterfly4, ph2 ) ) - Nz( ValueWhen( BullButterfly4, tl2 ) ) ) * ButCDXAMin AND
                         Nz( LowestSince( BullButterfly4, L ) ) > Nz( ValueWhen( BullButterfly4, ph2 ) ) - ( Nz( ValueWhen( BullButterfly4, ph2 ) ) - Nz( ValueWhen( BullButterfly4, tl2 ) ) ) * ButCDXAmax AND
                         Nz( HighestSince( BullButterfly4, H ) ) <= Nz( ValueWhen( BullButterfly4, ph1 ) ) AND
                         Nz( LowestSince( BullButterfly4, L ) ) < Nz( ValueWhen( BullButterfly4, tl2 ) ) AND
                         Nz( trn ) AND
                         Nz( LowestSince( bullButterfly4, L ) ) == L, True, False );
}

if( dCrab AND bu )
{
    BullCrab4 = PTvalid AND( ph2 - tl1 ) / ( ph2 - tl2 ) > CraABXAmin AND( ph2 - tl1 ) / ( ph2 - tl2 ) < CraABXAmax
                AND( ph1 - tl1 ) / ( ph2 - tl1 ) > CraBCABmin AND( ph1 - tl1 ) / ( ph2 - tl1 ) < CraBCABmax;
    BullCrab = IIf( Nz( LowestSince( BullCrab4, L ) ) < Nz( ValueWhen( BullCrab4, ph2 ) ) - ( Nz( ValueWhen( BullCrab4, ph2 ) ) - Nz( ValueWhen( BullCrab4, tl2 ) ) ) * CraCDXAmin AND
                    Nz( LowestSince( BullCrab4, L ) ) > Nz( ValueWhen( BullCrab4, ph2 ) ) - ( Nz( ValueWhen( BullCrab4, ph2 ) ) - Nz( ValueWhen( BullCrab4, tl2 ) ) ) * CraCDXAmax AND
                    Nz( HighestSince( BullCrab4, H ) ) <= Nz( ValueWhen( BullCrab4, ph1 ) ) AND
                    Nz( LowestSince( BullCrab4, L ) ) < Nz( ValueWhen( BullCrab4, tl2 ) ) AND
                    Nz( trn ) AND
                    Nz( LowestSince( bullGartley4, L ) ) == L, True, False );
}

BullCrab = BullCrab AND
           IIf( Nz( ValueWhen( BullCrab4, bi ) ) >= Nz( ValueWhen( BullGartley4, bi ) ) AND
                Nz( ValueWhen( BullCrab4, bi ) ) >= Nz( ValueWhen( BullBat4, bi ) ) AND
                Nz( ValueWhen( BullCrab4, bi ) ) >= Nz( ValueWhen( BullButterfly4, bi ) ), 1, 0 );

BullBat = BullBat AND
          IIf( Nz( ValueWhen( BullBat4, bi ) ) >= Nz( ValueWhen( BullGartley4, bi ) ) AND
               Nz( ValueWhen( BullBat4, bi ) ) >= Nz( ValueWhen( BullCrab4, bi ) ) AND
               Nz( ValueWhen( BullBat4, bi ) ) >= Nz( ValueWhen( BullButterfly4, bi ) ), 1, 0 );

BullButterfly = BullButterfly AND
                IIf( Nz( ValueWhen( BullButterfly4, bi ) ) >= Nz( ValueWhen( BullGartley4, bi ) ) AND
                     Nz( ValueWhen( BullButterfly4, bi ) ) >= Nz( ValueWhen( BullCrab4, bi ) ) AND
                     Nz( ValueWhen( BullButterfly4, bi ) ) >= Nz( ValueWhen( BullBat4, bi ) ), 1, 0 );

BullGartley = BullGartley AND
              IIf( Nz( ValueWhen( BullGartley4, bi ) ) >= Nz( ValueWhen( BullBat4, bi ) ) AND
                   Nz( ValueWhen( BullGartley4, bi ) ) >= Nz( ValueWhen( BullCrab4, bi ) ) AND
                   Nz( ValueWhen( BullGartley4, bi ) ) >= Nz( ValueWhen( BullButterfly4, bi ) ), 1, 0 );

BullHar4 = BullGartley4 OR BullButterfly4 OR BullBat4 OR BullCrab4 ;
BullHar = BullGartley OR BullButterfly OR BullBat OR BullCrab ;

buXy = ValueWhen( BullHar4, tl2 );
buXx = ValueWhen( BullHar4, tx2 );
buAy = ValueWhen( BullHar4, ph2 );
buAx = ValueWhen( BullHar4, px2 );
buBy = ValueWhen( BullHar4, tl1 );
buBx = ValueWhen( BullHar4, tx1 );
buCy = ValueWhen( BullHar4, ph1 );
buCx = ValueWhen( BullHar4, px1 );
buDy = ValueWhen( BullHar, L );
buDx = ValueWhen( BullHar, bi );

buABdXA = ( buAy - buBy ) / ( buAy - buXy );
buBCdAB = ( buCy - buBy ) / ( buAy - buBy );
buADdXA = ( buAy - buDy ) / ( buAy - buXy );
buBCdCD = ( buCy - buDy ) / ( buCy - buBy );

function drawBullishPattern( i, patternName )
{
    GfxSetZOrder( -1 );
    GfxSelectPen( ColorRGB( 0, 0, 255 ), 1, 5 );
    GfxSelectSolidBrush( ColorRGB( 0, 0, 50 ) );
    GfxPolygon( buXx[i], buXy[i], buAx[i], buAy[i], buBx[i], buBy[i], buCx[i], buCy[i], buDx[i], buDy[i], buBx[i], buBy[i], buXx[i], buXy[i] );

    GfxSelectPen( ColorRGB( 0, 0, 255 ), 2, 0 );
    GfxMoveTo( buXx[i], buXy[i] );
    GfxLineTo( buAx[i], buAy[i] );
    GfxMoveTo( buAx[i], buAy[i] );
    GfxLineTo( buBx[i], buBy[i] );
    GfxMoveTo( buBx[i], buBy[i] );
    GfxLineTo( buCx[i], buCy[i] );
    GfxMoveTo( buCx[i], buCy[i] );
    GfxLineTo( buDx[i], buDy[i] );
    GfxMoveTo( buXx[i], buXy[i] );
    GfxLineTo( buAx[i], buAy[i] );

    GfxSelectPen( ColorRGB( 0, 0, 255 ), 1, 2 );
    GfxMoveTo( buXx[i], buXy[i] );
    GfxLineTo( buBx[i], buBy[i] );
    GfxMoveTo( buAx[i], buAy[i] );
    GfxLineTo( buCx[i], buCy[i] );
    GfxMoveTo( buBx[i], buBy[i] );
    GfxLineTo( buDx[i], buDy[i] );
    GfxMoveTo( buXx[i], buXy[i] );
    GfxLineTo( buDx[i], buDy[i] );

    if( showPatternName )
    {
        GfxSetZOrder( 1 );
        GfxSetCoordsMode( 1 );
        GfxSetTextColor( ColorRGB( 0, 100, 255 ) );
        GfxSelectFont( "Helvetica", 10, 700 );
        GfxSetTextAlign( 0 | 8 );
        GfxTextOut( patternName, buCx[i] + 4, buCy[i] );
    }

    GfxSetZOrder( 1 );
    GfxSetTextAlign( 0 | 0 );
    GfxSetTextColor( ColorRGB( 0, 150, 255 ) );
    GfxSelectFont( "Helvetica", 8, 700 );
    GfxTextOut( "" + Prec( buABdXA[i], 2 ), ( buBx[i] + buXx[i] ) / 2, ( buBy[i] + buXy[i] ) / 2 );
    GfxTextOut( "" + Prec( buBCdAB[i], 2 ), ( buCx[i] + buAx[i] ) / 2, ( buCy[i] + buAy[i] ) / 2 );
    GfxTextOut( "" + Prec( buADdXA[i], 2 ), ( buDx[i] + buXx[i] ) / 2, ( buDy[i] + buXy[i] ) / 2 );
    GfxTextOut( "" + Prec( buBCdCD[i], 2 ), ( buBx[i] + buDx[i] ) / 2, ( buBy[i] + buDy[i] ) / 2 );

    if( showPatternLabels )
    {
        GfxSetZOrder( 1 );
        GfxSetTextColor( ColorRGB( 0, 150, 255 ) );
        GfxSelectFont( "Helvetica", 11, 700 );
        GfxSetTextAlign( 0 | 24 );
        GfxTextOut( "X", buXx[i] - 2, buXy[i] );
        GfxTextOut( "A", buAx[i] - 2, buAy[i] );
        GfxTextOut( "B", buBx[i] - 2, buBy[i] );
        GfxTextOut( "C", buCx[i] + 1, buCy[i] );
        GfxTextOut( "D", buDx[i] + 1, buDy[i] );
    }
}

function drawBullishReversalZone( i, CDXAmin, CDXAmax, cntzones, pname )
{
    clr1 = ColorRGB( 0, 80 + cntzones * colorContrastFactor, 140 + cntzones * colorContrastFactor );
    clr2 = ColorRGB( 0, 20 + cntzones * colorContrastFactor, 35 + cntzones * colorContrastFactor );

    GfxSetZOrder( 1 );
    GfxSelectPen( clr1, 1, 1 );
    GfxMoveTo( buCx[i], buAy[i] - ( buAy[i] - buXy[i] )*CDXAmin );
    GfxLineTo( Max( i, buDx[i] ), buAy[i] - ( buAy[i] - buXy[i] )*CDXAmin );
    GfxMoveTo( buCx[i], buAy[i] - ( buAy[i] - buXy[i] )*CDXAmin );
    GfxLineTo( buCx[i], buAy[i] - ( buAy[i] - buXy[i] )*CDXAmax );
    GfxMoveTo( buCx[i], buAy[i] - ( buAy[i] - buXy[i] )*CDXAmax );
    GfxLineTo( Max( i, buDx[i] ), buAy[i] - ( buAy[i] - buXy[i] )*CDXAmax );
    GfxMoveTo( Max( i, buDx[i] ), buAy[i] - ( buAy[i] - buXy[i] )*CDXAmin );
    GfxLineTo( Max( i, buDx[i] ), buAy[i] - ( buAy[i] - buXy[i] )*CDXAmax );

    GfxSetZOrder( -2 );
    GfxSelectSolidBrush( clr2 );
    GfxPolygon( buCx[i], buAy[i] - ( buAy[i] - buXy[i] )*CDXAmin,
                Max( i, buDx[i] ), buAy[i] - ( buAy[i] - buXy[i] )*CDXAmin,
                Max( i, buDx[i] ), buAy[i] - ( buAy[i] - buXy[i] )*CDXAmax,
                buCx[i], buAy[i] - ( buAy[i] - buXy[i] )*CDXAmax,
                buCx[i], buAy[i] - ( buAy[i] - buXy[i] )*CDXAmin );

    GfxSetZOrder( 1 );
    GfxSetTextColor( ColorRGB( 0, 100, 255 ) );
    GfxSelectFont( "Helvetica", 7, 700 );
    GfxSetTextAlign( 0 | 8 );
    GfxTextOut( pname, buCx[i] + 0, buAy[i] - ( buAy[i] - buXy[i] )*CDXAmin );
}
function drawBullishPatterns()
{
    flag1 = 1;
    flag2 = 0;
    cnt = 0;

    for( i = lvb; i > fvb; i-- )
    {
        if( BullHar[i] AND flag1 AND cnt < nBull )
        {
            flag1 = 0;
            flag2 = 1;
            cnt = cnt + 1;

            if( BullButterfly[i] AND bu AND dBut )
            {
                drawBullishPattern( i, "Bullish Butterfly" );
            }
            else
                if( BullCrab[i] AND bu AND dCrab )
                {
                    drawBullishPattern( i, "Bullish Crab" );
                }
                else
                    if( BullBat[i] AND bu AND dBat )
                    {
                        drawBullishPattern( i, "Bullish Bat" );
                    }
                    else
                        if( BullGartley[i] AND bu AND dGart )
                        {
                            drawBullishPattern( i, "Bullish Gartley" );
                        }
        }

        if( BullHar4[i] AND flag2 )
        {
            flag1 = 1;
            flag2 = 0;
        }
    }
}
function manageBullishReversalZones()
{
    cnt = 0;
    cntzones = 0;
    ButFlag1 = 1;
    CraFlag1 = 1;
    BatFlag1 = 1;
    GarFlag1 = 1;
    yMax = yMin = 0;

    for( i = lvb; i > fvb; i-- )
    {
        if( BullButterfly[i] AND bu AND dBut AND ButFlag1 AND( L[i] < yMin OR L[i] > yMax[i] ) )
        {
            ButFlag1 = 0;
            CraFlag1 = 1;
            BatFlag1 = 1;
            GarFlag1 = 1;

            drawBullishReversalZone( i, ButCDXAmin, ButCDXAmax, cntzones, "Butterfly" );

            yMax = buAy[i] - ( buAy[i] - buXy[i] ) * ButCDXAmax;
            yMin = buAy[i] - ( buAy[i] - buXy[i] ) * ButCDXAmin;

            cntzones = cntzones + 1;
        }

        if( BullCrab[i] AND bu AND dCrab AND CraFlag1 AND( L[i] < yMin OR L[i] > yMax[i] ) )
        {
            ButFlag1 = 1;
            CraFlag1 = 0;
            BatFlag1 = 1;
            GarFlag1 = 1;

            drawBullishReversalZone( i, CraCDXAmin, CraCDXAmax, cntzones, "Crab" );

            yMax = buAy[i] - ( buAy[i] - buXy[i] ) * CraCDXAmax;
            yMin = buAy[i] - ( buAy[i] - buXy[i] ) * CraCDXAmin;

            cntzones = cntzones + 1;
        }

        if( BullBat[i] AND bu AND dBat AND BatFlag1 AND( L[i] < yMin OR L[i] > yMax[i] ) )
        {
            ButFlag1 = 1;
            CraFlag1 = 1;
            BatFlag1 = 0;
            GarFlag1 = 1;

            drawBullishReversalZone( i, BatCDXAmin, BatCDXAmax, cntzones, "Bat" );

            yMax = buAy[i] - ( buAy[i] - buXy[i] ) * BatCDXAmax;
            yMin = buAy[i] - ( buAy[i] - buXy[i] ) * BatCDXAmin;

            cntzones = cntzones + 1;
        }

        if( BullGartley[i] AND bu AND dGart AND GarFlag1 AND( L[i] < yMin OR L[i] > yMax[i] ) )
        {
            ButFlag1 = 1;
            CraFlag1 = 1;
            BatFlag1 = 1;
            GarFlag1 = 0;

            drawBullishReversalZone( i, GarCDXAmin, GarCDXAmax, cntzones, "Gartley" );

            yMax = buAy[i] - ( buAy[i] - buXy[i] ) * GarCDXAmax;
            yMin = buAy[i] - ( buAy[i] - buXy[i] ) * GarCDXAmin;

            cntzones = cntzones + 1;
        }

        if( BullHar4[i] )
        {
            ButFlag1 = 1;
            CraFlag1 = 1;
            BatFlag1 = 1;
            GarFlag1 = 1;
            cnt = cnt + 1;
            yMax = 0;
            yMin = 0;
            cntzones = 0;
        }

        if( cnt >= nBull ) break;
    }
}
drawBullishPatterns();

if( showReversalZone ) manageBullishReversalZones();

// +++ Bearish Patterns
PTvalid = ( tx1 > px1 AND px1 > tx2 AND tx2 > px2 ) AND tr;

if( dGart AND be )
{
    BearGartley4 = PTvalid AND( ph1 - tl2 ) / ( ph2 - tl2 ) > GarABXAmin AND( ph1 - tl2 ) / ( ph2 - tl2 ) < GarABXAmax AND
                   ( ph1 - tl1 ) / ( ph1 - tl2 ) > GarBCABmin AND( ph1 - tl1 ) / ( ph1 - tl2 ) < GarBCABmax;
    BearGartley = IIf( Nz( HighestSince( bearGartley4, H ) ) > Nz( ValueWhen( BearGartley4, tl2 ) ) + ( Nz( ValueWhen( BearGartley4, ph2 ) ) - Nz( ValueWhen( BearGartley4, tl2 ) ) ) * GarCDXAmin AND
                       Nz( HighestSince( bearGartley4, H ) ) < Nz( ValueWhen( BearGartley4, tl2 ) ) + ( Nz( ValueWhen( BearGartley4, ph2 ) ) - Nz( ValueWhen( BearGartley4, tl2 ) ) ) * GarCDXAMax AND
                       Nz( LowestSince( BearGartley4, L ) ) >= Nz( ValueWhen( BearGartley4, tl1 ) ) AND
                       Nz( HighestSince( BearGartley4, H ) ) > Nz( ValueWhen( BearGartley4, ph1 ) ) AND
                       Nz( pkn ) AND
                       Nz( HighestSince( BearGartley4, H ) ) == H, True, False );
}

if( dBat AND be )
{
    BearBat4 = PTvalid AND( ph1 - tl2 ) / ( ph2 - tl2 ) > BatABXAmin AND( ph1 - tl2 ) / ( ph2 - tl2 ) < BatABXAmax AND
               ( ph1 - tl1 ) / ( ph1 - tl2 ) > BatBCABmin AND( ph1 - tl1 ) / ( ph1 - tl2 ) < BatBCABmax;
    BearBat = IIf( Nz( HighestSince( BearBat4, H ) ) > Nz( ValueWhen( BearBat4, tl2 ) ) + ( Nz( ValueWhen( BearBat4, ph2 ) ) - Nz( ValueWhen( BearBat4, tl2 ) ) ) * BatCDXAmin AND
                   Nz( HighestSince( BearBat4, H ) ) < Nz( ValueWhen( BearBat4, tl2 ) ) + ( Nz( ValueWhen( BearBat4, ph2 ) ) - Nz( ValueWhen( BearBat4, tl2 ) ) ) * BatCDXAMax AND
                   Nz( LowestSince( BearBat4, L ) ) >= Nz( ValueWhen( BearBat4, tl1 ) ) AND
                   Nz( HighestSince( BearBat4, H ) ) > Nz( ValueWhen( BearBat4, ph1 ) ) AND
                   Nz( pkn ) AND
                   Nz( HighestSince( BearBat4, H ) ) == H, True, False );
}

if( dBut AND be )
{
    BearButterfly4 = PTvalid AND( ph1 - tl2 ) / ( ph2 - tl2 ) > ButABXAmin AND( ph1 - tl2 ) / ( ph2 - tl2 ) < ButABXAmax AND
                     ( ph1 - tl1 ) / ( ph1 - tl2 ) > ButBCABmin AND( ph1 - tl1 ) / ( ph1 - tl2 ) < ButBCABmax;
    BearButterfly = IIf( Nz( HighestSince( BearButterfly4, H ) ) > Nz( ValueWhen( BearButterfly4, tl2 ) ) + ( Nz( ValueWhen( BearButterfly4, ph2 ) ) - Nz( ValueWhen( BearButterfly4, tl2 ) ) ) * ButCDXAmin AND
                         Nz( HighestSince( BearButterfly4, H ) ) < Nz( ValueWhen( BearButterfly4, tl2 ) ) + ( Nz( ValueWhen( BearButterfly4, ph2 ) ) - Nz( ValueWhen( BearButterfly4, tl2 ) ) ) * ButCDXAMax AND
                         Nz( LowestSince( BearButterfly4, L ) ) >= Nz( ValueWhen( BearButterfly4, tl1 ) ) AND
                         Nz( HighestSince( BearButterfly4, H ) ) > Nz( ValueWhen( BearButterfly4, ph2 ) ) AND
                         Nz( pkn ) AND
                         Nz( HighestSince( BearButterfly4, H ) ) == H, True, False );
}

if( dCrab AND be )
{
    BearCrab4 = PTvalid AND( ph1 - tl2 ) / ( ph2 - tl2 ) > CraABXAmin AND( ph1 - tl2 ) / ( ph2 - tl2 ) < CraABXAmax AND
                ( ph1 - tl1 ) / ( ph1 - tl2 ) > CraBCABmin AND( ph1 - tl1 ) / ( ph1 - tl2 ) < CraBCABmax;
    BearCrab = IIf( Nz( HighestSince( BearCrab4, H ) ) > Nz( ValueWhen( BearCrab4, tl2 ) ) + ( Nz( ValueWhen( BearCrab4, ph2 ) ) - Nz( ValueWhen( BearCrab4, tl2 ) ) ) * CraCDXAmin AND
                    Nz( HighestSince( BearCrab4, H ) ) < Nz( ValueWhen( BearCrab4, tl2 ) ) + ( Nz( ValueWhen( BearCrab4, ph2 ) ) - Nz( ValueWhen( BearCrab4, tl2 ) ) ) * CraCDXAMax AND
                    Nz( LowestSince( BearCrab4, L ) ) >= Nz( ValueWhen( BearCrab4, tl1 ) ) AND
                    Nz( HighestSince( BearCrab4, H ) ) > Nz( ValueWhen( BearCrab4, ph2 ) ) AND
                    Nz( pkn ) AND
                    Nz( HighestSince( BearCrab4, H ) ) == H, True, False );
}

BearCrab = BearCrab AND
           IIf( Nz( ValueWhen( BearCrab4, bi ) ) >= Nz( ValueWhen( BearGartley4, bi ) ) AND
                Nz( ValueWhen( BearCrab4, bi ) ) >= Nz( ValueWhen( BearBat4, bi ) ) AND
                Nz( ValueWhen( BearCrab4, bi ) ) >= Nz( ValueWhen( BearButterfly4, bi ) ), 1, 0 );

BearBat = BearBat AND
          IIf( Nz( ValueWhen( BearBat4, bi ) ) >= Nz( ValueWhen( BearGartley4, bi ) ) AND
               Nz( ValueWhen( BearBat4, bi ) ) >= Nz( ValueWhen( BearCrab4, bi ) ) AND
               Nz( ValueWhen( BearBat4, bi ) ) >= Nz( ValueWhen( BearButterfly4, bi ) ), 1, 0 );

BearButterfly = BearButterfly AND
                IIf( Nz( ValueWhen( BearButterfly4, bi ) ) >= Nz( ValueWhen( BearGartley4, bi ) ) AND
                     Nz( ValueWhen( BearButterfly4, bi ) ) >= Nz( ValueWhen( BearCrab4, bi ) ) AND
                     Nz( ValueWhen( BearButterfly4, bi ) ) >= Nz( ValueWhen( BearBat4, bi ) ), 1, 0 );

BearGartley = BearGartley AND
              IIf( Nz( ValueWhen( BearGartley4, bi ) ) >= Nz( ValueWhen( BearBat4, bi ) ) AND
                   Nz( ValueWhen( BearGartley4, bi ) ) >= Nz( ValueWhen( BearCrab4, bi ) ) AND
                   Nz( ValueWhen( BearGartley4, bi ) ) >= Nz( ValueWhen( BearButterfly4, bi ) ), 1, 0 );

BearHar4 = BearGartley4 OR BearButterfly4 OR BearBat4 OR BearCrab4 ;
BearHar = BearGartley OR BearButterfly OR BearBat OR BearCrab ;

beXy = ValueWhen( BearHar4, ph2 );
beXx = ValueWhen( BearHar4, px2 );
beAy = ValueWhen( BearHar4, tl2 );
beAx = ValueWhen( BearHar4, tx2 );
beBy = ValueWhen( BearHar4, ph1 );
beBx = ValueWhen( BearHar4, px1 );
beCy = ValueWhen( BearHar4, tl1 );
beCx = ValueWhen( BearHar4, tx1 );
beDy = ValueWhen( BearHar, H );
beDx = ValueWhen( BearHar, bi );

beABdXA = ( beBy - beAy ) / ( beXy - beAy );
beBCdAB = ( beBy - beCy ) / ( beBy - beAy );
beADdXA = ( beDy - beAy ) / ( beXy - beAy );
beBCdCD = ( beDy - beCy ) / ( beBy - beCy );

function drawBearishPattern( i, patternName )
{
    GfxSetZOrder( -1 );
    GfxSelectPen( ColorRGB( 255, 0, 0 ), 1, 5 ); // invisible pen to remove blue hue
    GfxSelectSolidBrush( ColorRGB( 50, 0, 0 ) );
    GfxPolygon( beXx[i], beXy[i], beAx[i], beAy[i], beBx[i], beBy[i], beCx[i], beCy[i], beDx[i], beDy[i], beBx[i], beBy[i], beXx[i], beXy[i] );

    GfxSelectPen( ColorRGB( 255, 0, 0 ), 2, 0 );
    GfxMoveTo( beXx[i], beXy[i] );
    GfxLineTo( beAx[i], beAy[i] );
    GfxMoveTo( beAx[i], beAy[i] );
    GfxLineTo( beBx[i], beBy[i] );
    GfxMoveTo( beBx[i], beBy[i] );
    GfxLineTo( beCx[i], beCy[i] );
    GfxMoveTo( beCx[i], beCy[i] );
    GfxLineTo( beDx[i], beDy[i] );
    GfxMoveTo( beXx[i], beXy[i] );
    GfxLineTo( beAx[i], beAy[i] );

    GfxSelectPen( ColorRGB( 255, 0, 0 ), 1, 2 );
    GfxMoveTo( beXx[i], beXy[i] );
    GfxLineTo( beBx[i], beBy[i] );
    GfxMoveTo( beAx[i], beAy[i] );
    GfxLineTo( beCx[i], beCy[i] );
    GfxMoveTo( beBx[i], beBy[i] );
    GfxLineTo( beDx[i], beDy[i] );
    GfxMoveTo( beXx[i], beXy[i] );
    GfxLineTo( beDx[i], beDy[i] );

    if( showPatternName )
    {
        GfxSetZOrder( 1 );
        GfxSetTextColor( ColorRGB( 255, 100, 0 ) );
        GfxSelectFont( "Helvetica", 10, 700 );
        GfxSetTextAlign( 0 | 0 );
        GfxTextOut( patternName, beCx[i] + 3, beCy[i] );
    }

    GfxSetZOrder( 1 );
    GfxSetTextAlign( 0 | 0 );
    GfxSetTextColor( ColorRGB( 255, 150, 50 ) );
    GfxSelectFont( "Helvetica", 8, 700 );
    GfxTextOut( "" + Prec( beABdXA[i], 2 ), ( beBx[i] + beXx[i] ) / 2, ( beBy[i] + beXy[i] ) / 2 );
    GfxTextOut( "" + Prec( beBCdAB[i], 2 ), ( beCx[i] + beAx[i] ) / 2, ( beCy[i] + beAy[i] ) / 2 );
    GfxTextOut( "" + Prec( beADdXA[i], 2 ), ( beDx[i] + beXx[i] ) / 2, ( beDy[i] + beXy[i] ) / 2 );
    GfxTextOut( "" + Prec( beBCdCD[i], 2 ), ( beBx[i] + beDx[i] ) / 2, ( beBy[i] + beDy[i] ) / 2 );

    if( showPatternLabels )
    {
        GfxSetZOrder( 1 );
        GfxSetTextColor( ColorRGB( 255, 150, 0 ) );
        GfxSelectFont( "Helvetica", 11, 700 );
        GfxSetTextAlign( 0 | 24 );
        GfxTextOut( "X", beXx[i] - 2, beXy[i] );
        GfxTextOut( "A", beAx[i] - 2, beAy[i] );
        GfxTextOut( "B", beBx[i] - 2, beBy[i] );
        GfxTextOut( "C", beCx[i] + 1, beCy[i] );
        GfxTextOut( "D", beDx[i] + 1, beDy[i] );
    }
}
function drawBearishReversalZone( i, CDXAmin, CDXAmax, cntzones, pname )
{
    clr1 = ColorRGB( 160 + cntzones * colorContrastFactor, 80 + cntzones * colorContrastFactor, 0 );
    clr2 = ColorRGB( 35 + cntzones * colorContrastFactor, 15 + cntzones * colorContrastFactor, 0 );

    GfxSetZOrder( 1 );
    GfxSelectPen( clr1, 1, 1 );
    GfxMoveTo( beCx[i], beAy[i] - ( beAy[i] - beXy[i] )*CDXAmin );
    GfxLineTo( Max( i, beDx[i] ), beAy[i] - ( beAy[i] - beXy[i] )*CDXAmin );
    GfxMoveTo( beCx[i], beAy[i] - ( beAy[i] - beXy[i] )*CDXAmin );
    GfxLineTo( beCx[i], beAy[i] - ( beAy[i] - beXy[i] )*CDXAmax );
    GfxMoveTo( beCx[i], beAy[i] - ( beAy[i] - beXy[i] )*CDXAmax );
    GfxLineTo( Max( i, beDx[i] ), beAy[i] - ( beAy[i] - beXy[i] )*CDXAmax );
    GfxMoveTo( Max( i, beDx[i] ), beAy[i] - ( beAy[i] - beXy[i] )*CDXAmin );
    GfxLineTo( Max( i, beDx[i] ), beAy[i] - ( beAy[i] - beXy[i] )*CDXAmax );

    GfxSetZOrder( -2 );
    GfxSelectSolidBrush( clr2 );
    GfxPolygon( beCx[i], beAy[i] - ( beAy[i] - beXy[i] )*CDXAmin,
                Max( i, beDx[i] ), beAy[i] - ( beAy[i] - beXy[i] )*CDXAmin,
                Max( i, beDx[i] ), beAy[i] - ( beAy[i] - beXy[i] )*CDXAmax,
                beCx[i], beAy[i] - ( beAy[i] - beXy[i] )*CDXAmax,
                beCx[i], beAy[i] - ( beAy[i] - beXy[i] )*CDXAmin );

    GfxSetZOrder( 1 );
    GfxSetTextColor( ColorRGB( 255, 100, 0 ) );
    GfxSelectFont( "Helvetica", 7, 700 );
    GfxSetTextAlign( 0 | 0 );
    GfxTextOut( pname, beCx[i] + 0, beAy[i] - ( beAy[i] - beXy[i] )*CDXAmin );
}
function drawBearishPatterns()
{
    flag1 = 1;
    flag2 = 0;
    cnt = 0;

    for( i = lvb; i > fvb; i-- )
    {
        if( BearHar[i] AND flag1 AND cnt < nBear )
        {
            flag1 = 0;
            flag2 = 1;
            cnt = cnt + 1;

            if( BearButterfly[i] AND be AND dBut )
            {
                drawBearishPattern( i, "Bearish Butterfly" );
            }
            else
                if( BearCrab[i] AND be AND dCrab )
                {
                    drawBearishPattern( i, "Bearish Crab" );
                }

                else
                    if( BearBat[i] AND be AND dBat )
                    {
                        drawBearishPattern( i, "Bearish Bat" );
                    }

                    else
                        if( BearGartley[i] AND be AND dGart )
                        {
                            drawBearishPattern( i, "Bearish Gartley" );
                        }
        }

        if( BearHar4[i] AND flag2 )
        {
            flag1 = 1;
            flag2 = 0;
        }
    }
}
function manageBearishReversalZones()
{
    cnt = 0;
    cntzones = 0;
    ButFlag1 = 1;
    CraFlag1 = 1;
    BatFlag1 = 1;
    GarFlag1 = 1;
    yMax = yMin = 0;

    for( i = lvb; i > fvb; i-- )
    {
        if( BearButterfly[i] AND be AND dBut AND ButFlag1 AND( H[i] > yMax OR H[i] < yMin ) )
        {
            ButFlag1 = 0;
            CraFlag1 = 1;
            BatFlag1 = 1;
            GarFlag1 = 1;

            drawBearishReversalZone( i, ButCDXAmin, ButCDXAmax, cntzones, "Butterfly" );

            yMax = beAy[i] - ( beAy[i] - beXy[i] ) * ButCDXAmax;
            yMin = beAy[i] - ( beAy[i] - beXy[i] ) * ButCDXAmin;

            cntzones = cntzones + 1;
        }

        if( BearCrab[i] AND be AND dCrab AND CraFlag1  AND( H[i] > yMax OR H[i] < yMin ) )
        {
            ButFlag1 = 1;
            CraFlag1 = 0;
            BatFlag1 = 1;
            GarFlag1 = 1;

            drawBearishReversalZone( i, CraCDXAmin, CraCDXAmax, cntzones, "Crab" );

            yMax = beAy[i] - ( beAy[i] - beXy[i] ) * CraCDXAmax;
            yMin = beAy[i] - ( beAy[i] - beXy[i] ) * CraCDXAmin;

            cntzones = cntzones + 1;
        }

        if( BearBat[i] AND be AND dBat AND BatFlag1  AND( H[i] > yMax OR H[i] < yMin ) )
        {
            ButFlag1 = 1;
            CraFlag1 = 1;
            BatFlag1 = 0;
            GarFlag1 = 1;

            drawBearishReversalZone( i, BatCDXAmin, BatCDXAmax, cntzones, "Bat" );

            yMax = beAy[i] - ( beAy[i] - beXy[i] ) * BatCDXAmax;
            yMin = beAy[i] - ( beAy[i] - beXy[i] ) * BatCDXAmin;

            cntzones = cntzones + 1;
        }

        if( BearGartley[i] AND be AND dGart AND GarFlag1  AND( H[i] > yMax OR H[i] < yMin ) )
        {
            ButFlag1 = 1;
            CraFlag1 = 1;
            BatFlag1 = 1;
            GarFlag1 = 0;

            drawBearishReversalZone( i, GarCDXAmin, GarCDXAmax, cntzones, "Gartley" );

            yMax = beAy[i] - ( beAy[i] - beXy[i] ) * GarCDXAmax;
            yMin = beAy[i] - ( beAy[i] - beXy[i] ) * GarCDXAmin;

            cntzones = cntzones + 1;
        }

        if( BearHar4[i] )
        {
            ButFlag1 = 1;
            CraFlag1 = 1;
            BatFlag1 = 1;
            GarFlag1 = 1;
            cnt = cnt + 1;
            yMax = 0;
            yMin = 0;
            cntzones = 0;
        }

        if( cnt >= nBear ) break;
    }
}
drawBearishPatterns();

if( showReversalZone ) manageBearishReversalZones();

function drawPivotLabels()
{
    sz = 5;

    for( i = lvb; i > fvb; i-- )
    {
        {
            if( ll[i] ) PlotTextSetFont( "LL", "Arial Black", sz, i, L[i], colorBlue, colorDefault, -25 );

            if( hl[i] ) PlotTextSetFont( "HL", "Arial Black", sz, i, L[i], colorBlue, colorDefault, -25 );

            if( db[i] ) PlotTextSetFont( "DB", "Arial Black", sz, i, L[i], colorLightBlue, colorDefault, -25 );

            if( hh[i] ) PlotTextSetFont( "HH", "Arial Black", sz, i, H[i], colorRed, colorDefault, 20 );

            if( lh[i] ) PlotTextSetFont( "LH", "Arial Black", sz, i, H[i], colorRed, colorDefault, 20 );

            if( dt[i] ) PlotTextSetFont( "DT", "Arial Black", sz, i, H[i], colorOrange, colorDefault, 20 );
        }
    }
}

if( showLabels ) drawPivotLabels();

if( showPatternDevelopmentPoints )
{
    if( bu )
    {
        PlotShapes( shapeDigit4 * BullHar4, colorBlue, O, H, 35 );
        PlotShapes( shapeSmallCircle * BullHar, ColorLightBlue, O, L, -10 );
    }

    if( be )
    {
        PlotShapes( shapeDigit4 * BearHar4, colorRed, O, L, -35 );
        PlotShapes( shapeSmallCircle * BearHar, colorOrange, O, H, 10 );
    }
}

Title = Name() +
        " | " + Now( 2 ) +
        " | " + "PIVOT TIMEFRAME: " + tfrm / 60 + " Minutes or " + tfrm / 3600 + " Hours or " + tfrm / ( 3600 * 24 ) + " Days ";
Back