Volume profile code modification

Hi,

this is my 1st post in this forum. Have came across volume profile afl coded by Mr pottash. It works fine . My question is Can anyone add exploration for buy, sell signals...

Am pasting code over here....
/*
in reply to: How to get the most traded area value of previous day intraday data
!!!! TickSize is hardcoded in code. You need to adjust for, according to contract specifics.
E.M.Pottasch (10/2017)

some reading

possible strategies

Simplified array names. Value Area High, Value Area Low and the Point Of Control are now simply saved in arrays VAH, VAL
and VPOC. All the shifted arrays are stored in dynamic variable arrays. For instance VAH shifted 1 time segment
(for instance 1 day) to the right is called VAHn1, shifting it 2 segments, then it is called VAHn2. The array names are
shown in the chart at the respective levels.

As shown in the trading system example you need to first generate the levels by setting the "Shift Volume Value Area (Interval)"
in the param window correctly. Then you will also have to call them in the trading system. By default the n1 levels
are already set in the param window ("Shift Volume Value Area (Interval)" is by default set to 1 )

When using exploration or backtest ===> !!!*** use From- To Dates in analysis Window ***!!!
*/

TickSize = 0.05; // <<<<==== adjust yourself
if( TickSize == 0 )
{
TickSize = 0.01;
PopupWindow( "Ticksize is not set. The TickSize should be set in the code or in the Information Window", "TickSize Problem", 15, -1, -1, -1, -1, True );
}

GfxSetZOrder( -5 );
GfxSetCoordsMode( 1 );

volumeValueArea = Param( "Volume Value area (%)", 0.7, 0, 1, 0.01 );
showVolume = ParamToggle( "Show Volume", "No|Yes", 1 );
showHL = ParamToggle( "Show High/Low boundaries", "No|Yes", 0 );
showMain = ParamToggle( "Show main levels VAH, VAL and VPOC", "No|Yes", 0 );
showShifted = ParamToggle( "Show shifted levels VAHn1, VALn1, VPOCn1, etc", "No|Yes", 1 );
giveVolumeAreaColor = ParamToggle( "Give Volume Value Area Other color", "No|Yes", 1 );
sep = ParamList( "Separator Interval", "Day|Week|Month|Year", 0 );
fontType = ParamList( "GFX Font Type", "Tahoma|Arial|Verdana|Courier New|Times New Roman|Open Sans|Segoe UI|DejaVu Sans", 3 );
fontSize = Param( "GFX Font Size", 9, 1, 20, 1 );
lineWidth1 = Param( "GFX Main Volume area Line Width", 1, 1, 10, 1 );
lineWidth2 = Param( "GFX Volume Line Width", 1, 1, 10, 1 );
showLabel = ParamToggle( "Show Labels on Levels", "No|Yes", 1 );
shft = Param( "Shift Volume Value Area (Interval)", 1, 1, 10, 1 );

switch( sep )
{
case "Day":
dn = Day();
dn1 = inDaily;
break;

case "Week":
dw = DayOfWeek();
newWeek = dw < Ref( dw, -1 );;
newYear = Year() != Ref( Year(), -1 );
dn = weekNumber = Sum( newWeek, BarsSince( newYear ) + 1 );
dn1 = inWeekly;
break;

case "Month":
dn = Month();
dn1 = inMonthly;
break;

case "Year":
dn = Year();
dn1 = inYearly;
break;
}

separator = dn != Ref( dn, -1 );

bi = BarIndex();
fvb = Max( 0, FirstVisibleValue( bi ) );
lvb = Max( 0, LastVisibleValue( bi ) );

dif = 0;
mxih = mxil = 0;
Buy = Sell = Short = Cover = BuyPrice = SellPrice = ShortPrice = CoverPrice = 0;
VPOC = VAH = VAL = Null;
HOD = TimeFrameGetPrice( "H", dn1 );
LOD = TimeFrameGetPrice( "L", dn1 );

yesterdayClosePrice = TimeFrameGetPrice( "C", inDaily, -1 ); // yesterdays close
todayOpenPrice = ValueWhen( separator, O ); // todays open
tn = TimeNum();

for( i = 0; i <= 2 + shft; i++ )
{
VarSet( "lbx" + i, ValueWhen( separator, bi, i ) );
}

function drawHLine( x1, x2, y , clr, zorder, flag, txt, lw )
{
GfxSetZOrder( zorder );
GfxSelectPen( clr, lw, 0 );
GfxMoveTo( x1, y );
GfxLineTo( x2, y );

if( flag )
{
    GfxSetZOrder( 4 );
    GfxSetTextAlign( 2 | 8 );
    GfxSetBkColor( ColorRGB( 0, 0, 0 ) );
    GfxSetTextColor( clr );
    GfxSelectFont( fontType, fontSize );
    GfxTextOut( txt + Prec( y, 2 ), x2 , y );
}

}

function tradingStrategy1( fb, lb )
{
/*
Simple example trading system. Intended for intraday data.

	Call the dynamic arrays you use in your trading system. Make sure the parameter setting in the
	Param window is set correctly. In this case the default setting is sufficient.
*/

VAHn1 = VarGet( "VAHn1" );
VALn1 = VarGet( "VALn1" );
VPOCn1 = VarGet( "VPOCn1" );

Buy = ( ( todayOpenPrice > VAHn1 AND separator ) OR Cross( C, VAHn1 ) ) AND tn < 140000;
BuyPrice = C;
Sell = Cross( VPOCn1, C ) OR tn > 160000 OR Ref( separator, 1 );
SellPrice = C;
Buy = Buyo = ExRem( Buy, Sell );
Sell = Sello = ExRem( Sell, Buy );

Short = ( ( todayOpenPrice < VALn1 AND separator ) OR Cross( VALn1, C ) ) AND tn < 140000;
ShortPrice = C;
Cover = Cross( C, VPOCn1 ) OR tn > 160000 OR Ref( separator, 1 );
CoverPrice = C;
Short = Shorto = ExRem( Short, Cover );
Cover = Covero = ExRem( Cover, Short );

}

function calculateVolumeArea( mxVolBinIdx, totVol, bins, mx )
{
/*
Calculates Volume Value area.
I do just 1 step at a time. For the meaning of what I mean with steps see:
http://onlinelibrary.wiley.com/doi/10.1002/9781118659724.app1/pdf
*/
mxih = mxil = mxVolBinIdx;
tvol = mx[mxVolBinIdx][1];

for( j = 0; j < bins; j++ )
{
    if( mxih + 1 < bins AND mxil - 1 >= 0 )
    {
        relvolumeh = mx[mxih + 1][1];
        relvolumel = mx[mxil - 1][1];

        if( relvolumeh > relvolumel )
        {
            mxih = mxih + 1;
            tvol = tvol + relvolumeh;
        }
        else
            if( relvolumeh < relvolumel )
            {
                mxil = mxil - 1;
                tvol = tvol + relvolumel;
            }
            else
                if( relvolumeh == relvolumel )
                {
                    mxih = mxih + 1;
                    mxil = mxil - 1;
                    tvol = tvol + relvolumeh + relvolumel;
                }
    }
    else
        if( mxih + 1 >= bins AND mxil - 1 >= 0 )
        {
            relvolumel = mx[mxil - 1][1];
            mxil = mxil - 1;
            tvol = tvol + relvolumel;
        }
        else
            if( mxih + 1 < bins AND mxil - 1 < 0 )
            {
                relvolumeh = mx[mxih + 1][1];
                mxih = mxih + 1;
                tvol = tvol + relvolumeh;
            }

    if( ( tvol / totVol ) >= volumeValueArea ) break;
}

}

function calculateVolumeValueArea( fb, lb )
{
cnt = 0; // count number of visible days

for( i = lb; i > fb; i-- )
{
    idx0 = lbx0[i];
    idx1 = lbx1[i];
    idx2 = lbx2[i];

    if( IsEmpty( idx1 ) ) break;

    bins = int( ( HOD[idx1 - 1] - LOD[idx1 - 1] ) / TickSize );
    mx = PriceVolDistribution( H, L, V, bins, False, idx2, idx1 - 1 );
    dx = idx1 - idx2;

    mxVolBinIdx = 0;
    mxVol = 0;
    totVol = 0;

    for( j = 0; j < bins; j++ )
    {
        price = mx[j][0]; // price level
        relvolume = mx[j][1]; // relative volume 0..1
        relbar = relvolume * dx;

        if( showVolume AND Status( "Action" ) == actionIndicator )
        {
            //drawHLine( idx2, idx2 + relbar, price, ColorRGB( 60, 0, 0 ), -4, 0, "", lineWidth2 );
           drawHLine( idx2, idx2 + relbar, price, colorBrightGreen, -4, 0, "", lineWidth2 ); 
        }

        if( relvolume > mxVol )
        {
            mxVol = relvolume;
            mxVolBinIdx = j;
        }

        totVol = totVol + relvolume;
    }

    priceVPOC = mx[mxVolBinIdx][0];
    calculateVolumeArea( mxVolBinIdx, totVol, bins, mx );

    priceh = mx[mxih][0];
    pricel = mx[mxil][0];
    x1 = idx2;
    x2 = Min( idx1, BarCount - 1 );

    line = Ref( LineArray( x1, priceh, x2, priceh ), 1 );
    VAH = IIf( !IsEmpty( line ), line, VAH );
    line = Ref( LineArray( x1, pricel, x2, pricel ), 1 );
    VAL = IIf( !IsEmpty( line ), line, VAL );
    line = Ref( LineArray( x1, priceVPOC, x2, priceVPOC ), 1 );
    VPOC = IIf( !IsEmpty( line ), line, VPOC );

    // give volume value area other color
    if( giveVolumeAreaColor AND Status( "Action" ) == actionIndicator )
    {
        for( j = 0; j < bins; j++ )
        {
            price = mx[j][0]; // price level
            relvolume = mx[j][1]; // relative volume 0..1
            relbar = relvolume * dx;

            if( showVolume AND price >= pricel AND price <= priceh )
            {
               // drawHLine( idx2, idx2 + relbar, price, ColorRGB( 0, 40, 0 ), -4, 0, "", lineWidth2 + 0 );
               drawHLine( idx2, idx2 + relbar, price, colorWhite, -4, 0, "", lineWidth2 + 0 );
               
            }
        }
    }

    if( showHL AND Status( "Action" ) == actionIndicator )
    {
        ph = HOD[x2 - 1];
        drawHLine( x1, x2, ph, ColorRGB( 0, 250, 0 ), -3, showLabel, "HOD ", lineWidth1 );
        pl = LOD[x2 - 1];
        drawHLine( x1, x2, pl, ColorRGB( 250, 0, 0 ), -3, showLabel, "LOD ", lineWidth1 );
    }

    if( showMain AND Status( "Action" ) == actionIndicator )
    {
        drawHLine( x1, x2, priceh , ColorRGB( 0, 250, 250 ), -3, showLabel, "" + "VAH ", lineWidth1 );
        drawHLine( x1, x2, pricel , ColorRGB( 0, 250, 250 ), -3, showLabel, "" + "VAL ", lineWidth1 );
        drawHLine( x1, x2, priceVPOC , ColorRGB( 204, 77, 153 ), -3, showLabel, "" + "VPOC ", lineWidth1 );
    }

    if( cnt == 0 )
    {
        x1 = x2;
        x2 = Min( lvb, BarCount - 1 );

        if( x2 == 0 ) x2 = BarCount - 1;

        if( showHL AND Status( "Action" ) == actionIndicator )
        {
            ph = HOD[x2];
            drawHLine( x1, x2, ph, ColorRGB( 0, 250, 0 ), -3, showLabel, "HOD ", lineWidth1 );
            pl = LOD[x2];
            drawHLine( x1, x2, pl, ColorRGB( 250, 0, 0 ), -3, showLabel, "LOD ", lineWidth1 );
        }

        bins = int( ( HOD[x2] - LOD[x2] ) / TickSize );
        mx = PriceVolDistribution( H, L, V, bins, False, x1, x2 );
        dx = x2 - x1;

        mxVolBinIdx = 0;
        mxVol = 0;
        totVol = 0;

        for( j = 0; j < bins; j++ )
        {
            price = mx[j][0]; // price level
            relvolume = mx[j][1]; // relative volume 0..1
            relbar = relvolume * dx;

            if( showVolume AND Status( "Action" ) == actionIndicator ) drawHLine( x1, x1 + relbar, price, ColorRGB( 80, 80, 80 ), -4, 0, "", lineWidth2 );

            if( relvolume > mxVol )
            {
                mxVol = relvolume;
                mxVolBinIdx = j;
            }

            totVol = totVol + relvolume;
        }

        priceVPOC = mx[mxVolBinIdx][0];
        calculateVolumeArea( mxVolBinIdx, totVol, bins, mx );
        priceh = mx[mxih][0];
        pricel = mx[mxil][0];

        line = LineArray( x1, priceh, x2, priceh );
        VAH = IIf( !IsEmpty( line ), line, VAH );
        line = LineArray( x1, pricel, x2, pricel );
        VAL = IIf( !IsEmpty( line ), line, VAL );
        line = LineArray( x1, priceVPOC, x2, priceVPOC );
        VPOC = IIf( !IsEmpty( line ), line, VPOC );

        if( showMain AND Status( "Action" ) == actionIndicator )
        {
            drawHLine( x1, x2, priceh , ColorRGB( 0, 250, 250 ), -3, showLabel, "" + "VAH ", lineWidth1 );
            drawHLine( x1, x2, pricel , ColorRGB( 0, 250, 250 ), -3, showLabel, "" + "VAL ", lineWidth1 );
            drawHLine( x1, x2, priceVPOC , ColorRGB( 204, 77, 153 ), -3, showLabel, "" + "VPOC ", lineWidth1 );
        }

        if( giveVolumeAreaColor AND showVolume AND Status( "Action" ) == actionIndicator )
        {
            for( j = 0; j < bins; j++ )
            {
                price = mx[j][0]; // price level
                relvolume = mx[j][1]; // relative volume 0..1
                relbar = relvolume * dx;

                if( showVolume AND price >= pricel AND price <= priceh )
                {
                    drawHLine( x1, x1 + relbar, price, ColorRGB( 0, 40, 40 ), -4, 0, "", lineWidth2 );
                }
            }
        }
    }

    i = lbx1[ idx1 ];
    cnt++;
}

}

function shiftVolumeValueArea( fb, lb, shft )
{
for( i = lb; i > fb; i-- )
{
// destination index
if( lbx0[i] == lbx1[i] )
{
x1 = lbx1[i];
x2 = Min( lb, BarCount - 1 );
}
else
if( lbx1[i] < lbx0[i] )
{
x1 = lbx1[i];
x2 = Min( lb, lbx0[i] );
}

    for( s = 1; s <= shft; s++ )
    {
        xx0 = VarGet( "lbx" + ( s - 1 ) );
        xx1 = VarGet( "lbx" + ( s + 0 ) );
        xx2 = VarGet( "lbx" + ( s + 1 ) );

        if( xx0[i] == xx1[i] )
        {
            // source index
            x1s = xx2[i];
            x2s = xx1[i];

            if( !IsEmpty( x1s ) )
            {
                if( showShifted AND Status( "Action" ) == actionIndicator )
                {
                    drawHLine( x1, x2, VPOC[x1s] , ColorRGB( 250 / s, 0, 250 / s ), -3, showLabel, "VPOCn" + s + " ", lineWidth1 );
                    drawHLine( x1, x2, VAH[x1s] , ColorRGB( 250 / s, 250 / s, 0 ), -3, showLabel, "VAHn" + s + " ", lineWidth1 );
                    drawHLine( x1, x2, VAL[x1s] , ColorRGB( 250 / s, 250 / s, 0 ), -3, showLabel, "VALn" + s + " ", lineWidth1 );

                    //drawHLine( x1, x2, ( VAL[x1s] + VAH[x1s] ) / 2 , ColorRGB( 250 / s, 250 / s, 0 ), -3, showLabel, "VALn" + s + " ", 3 );
                }

                // save shifted value area in dynamic arrays
                if( !IsEmpty( VPOC[x1s] ) )
                {
                    line = Ref( LineArray( x1, VPOC[x1s], x2, VPOC[x1s] ), 1 );
                    VarSet( "VPOCn" + s, IIf( line, line, VarGet( "VPOCn" + s ) ) );
                }

                if( !IsEmpty( VAH[x1s] ) )
                {
                    line = Ref( LineArray( x1, VAH[x1s], x2, VAH[x1s] ), 1 );
                    VarSet( "VAHn" + s, IIf( line, line, VarGet( "VAHn" + s ) ) );
                }

                if( !IsEmpty( VAL[ x1s ] ) )
                {
                    line = Ref( LineArray( x1, VAL[x1s], x2, VAL[x1s] ), 1 );
                    VarSet( "VALn" + s, IIf( line, line, VarGet( "VALn" + s ) ) );
                }

            }
        }
        else
            if( xx1[i] < xx0[i] )
            {
                // source index
                x1s = xx2[i];
                x2s = xx1[i];

                if( !IsEmpty( x1s ) )
                {
                    if( showShifted AND Status( "Action" ) == actionIndicator )
                    {
                        drawHLine( x1, x2, VPOC[x1s] , ColorRGB( 250 / s, 0, 250 / s ), -3, showLabel, "VPOCn" + s + " ", lineWidth1 );
                        drawHLine( x1, x2, VAH[x1s] , ColorRGB( 250 / s, 250 / s, 0 ), -3, showLabel, "VAHn" + s + " ", lineWidth1 );
                        drawHLine( x1, x2, VAL[x1s] , ColorRGB( 250 / s, 250 / s, 0 ), -3, showLabel, "VALn" + s + " ", lineWidth1 );

                        //drawHLine( x1, x2, ( VAL[x1s] + VAH[x1s] ) / 2 , ColorRGB( 250 / s, 250 / s, 0 ), -3, showLabel, "VALn" + s + " ", 3 );
                    }

                    // save shifted value area in dynamic arrays
                    if( !IsEmpty( VPOC[x1s] ) )
                    {
                        line = Ref( LineArray( x1, VPOC[x1s], x2, VPOC[x1s] ), 1 );
                        VarSet( "VPOCn" + s, IIf( line, line, VarGet( "VPOCn" + s ) ) );
                    }

                    if( !IsEmpty( VAH[x1s] ) )
                    {
                        line = Ref( LineArray( x1, VAH[x1s], x2, VAH[x1s] ), 1 );
                        VarSet( "VAHn" + s, IIf( line, line, VarGet( "VAHn" + s ) ) );
                    }

                    if( !IsEmpty( VAL[x1s] ) )
                    {
                        line = Ref( LineArray( x1, VAL[x1s], x2, VAL[x1s] ), 1 );
                        VarSet( "VALn" + s, IIf( line, line, VarGet( "VALn" + s ) ) );
                    }
                }
            }
    }

    i = lbx1[i];
}

}

if( Status( "Action" ) == actionIndicator )
{
Title = Name() + " >>|<< Volume area (%): " + EncodeColor( colorYellow ) + volumeValueArea * 100 + EncodeColor( colorWhite ) + " >>|<< Separator Timeframe: " + sep;

SetChartOptions( 0, chartShowDates );
SetChartBkColor( ColorRGB( 0, 0, 0 ) );
Plot( Close, "Price", colorDefault, styleCandle, Null, Null, 0, 0, 1 );
Plot( separator, "", colorDarkBlue, styleHistogram | styleOwnScale | styleNoLabel | styleNoRescale, 0, 1, 0, -2, 5 );

br = Flip( fvb == bi, lvb == bi );
periods = IIf( br, separator, 0 );
periods = LastValue( Cum( periods ) );
dif = int( ( lvb - fvb ) / periods );
fvb = Max( 0, fvb - 2 * dif );

calculateVolumeValueArea( fvb, lvb );
shiftVolumeValueArea( fvb, lvb, shft );
tradingStrategy1( fvb, lvb );

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

}

if( Status( "Action" ) == actionExplore )
{
// !!!*** use From- To Dates in analysis Window ***!!!
br = Status( "barinrange" );
periods = IIf( br, separator, Null );
periods = LastValue( Cum( periods ) );

br = br - Ref( br, -1 );
st = LastValue( ValueWhen( br == 1, bi ) );
ed = LastValue( ValueWhen( br == ( -1 ), bi ) );

if( ed == 0 ) ed = BarCount - 1;

dif = int( ( ed - st ) / periods * shft );
st = Max( st - dif, 0 );

calculateVolumeValueArea( st, ed );
shiftVolumeValueArea( st, ed, shft );

Filter = ( separator == 1 );

AddColumn( Nz( VAH ) , "VAH", 1.2, colorBlack, ColorRGB( 0, 250, 250 ), -1 );

for( i = 1; i <= shft; i++ )
{
    AddColumn( Nz( VarGet( "VAHn" + i ) ), "VAHn" + i, 1.2, colorBlack, ColorRGB( 250, 250, 0 ), -1 );
}

AddColumn( Nz( VPOC ) , "VPOC", 1.2, colorBlack, ColorRGB( 204, 77, 153 ), -1 );

for( i = 1; i <= shft; i++ )
{
   AddColumn( Nz( VarGet( "VPOCn" + i ) ), "VPOCn" + i, 1.2, colorBlack, ColorRGB( 250, 0, 250 ), -1 );
}

AddColumn( Nz( VAL ) , "VAL", 1.2, colorBlack, ColorRGB( 0, 250, 250 ), -1 );

for( i = 1; i <= shft; i++ )
{
    AddColumn( Nz( VarGet( "VALn" + i ) ), "VALn" + i, 1.2, colorBlack, ColorRGB( 250, 250, 0 ), -1 );
}

}

if( Status( "Action" ) == actionBacktest )
{
// !!!*** use From- To Dates in analysis Window ***!!!
SetTradeDelays( 0, 0, 0, 0 );
SetOption( "FuturesMode", True );
SetOption( "MaxOpenPositions", 1 );
SetOption( "CommissionAmount", 2.02 );
SetPositionSize( 1, spsShares );

br = Status( "barinrange" );
periods = IIf( br, separator, Null );
periods = LastValue( Cum( periods ) );

br = br - Ref( br, -1 );
st = LastValue( ValueWhen( br == 1, bi ) );
ed = LastValue( ValueWhen( br == ( -1 ), bi ) );

if( ed == 0 ) ed = BarCount - 1;

if( periods * shft > 0 )
    dif = int( ( ed - st ) / periods * shft );

st = Max( st - dif, 0 );

calculateVolumeValueArea( st, ed );
shiftVolumeValueArea( st, ed, shft );
tradingStrategy1( st, ed );

}