How to get the most traded area value of previous day intraday data

How to get the value of the most traded area of previous day intraday chart

Did you take the time look at the example that @awilson offered you?

The help page for PriceVolDistribution has everything you need. Just interrogate the matrix it creates and find the price level from the first column that has the highest value of volume in the second column. No need to even draw it if you don’t want to.

To restrict the distribution to just the previous day’s price action, you can use detection of a new day to do that and replace fvb and lvb in the example. The LastValue function turns the resulting array value into a scalar PriceVolDistricution needs as an input, eg:

NewDay = Day() != Ref(Day(), -1);
bi = BarIndex();
fvb = LastValue(ValueWhen(NewDay, bi, 2)); // first bar of previous day
lvb = LastValue(ValueWhen(NewDay, bi, 1) - 1); // last bar one bar before the first bar of today

If you want the distribution to be one bin per tick of the previous day’s range, you can divide the previous day’s High minus the previous day’s Low by the Ticksize. Again LastValue will be needed if you are going to use the result as a looping parameter.

// one bin per tick of previous day's range
TickSize = 0.25; // set to the tick size for your market
bins = LastValue((TimeFrameGetPrice("H", inDaily, -1) - TimeFrameGetPrice("L", inDaily, -1)) / TickSize);

The rest you should be able to work out from the example on the PriceVolDistribution help page.

2 Likes

Iam Still facing issues of ,how it could done can you give me an example code of plotting that value of most traded place on previous days intraday data
Thankyou:cold_sweat:

If you want the ability to scroll back through the chart to see the most traded level for each prior day, then one way I could think of would be to build a loop which loops through the price history a day at a time, building a matrix with PriceVolDistribution for each day, and extracting and storing the result in dynamically named static variables. Then for the display, recall the the static variable for that day, then extract and display the value you need. Pre-processing this would mean it wouldn’t have to do the processing during the chart display each time, except maybe for the latest day.

A reasonable degree of coding skill would be required to achieve that solution.

But as with most things Amibroker, there are usually multiple ways to achieve the same result, so if there’s is a simpler solution than that, hopefully someone will jump on to this thread with it.

followed your steps but how get the most traded value in exploration

NewDay = Day() != Ref(Day(), -1);
bi = BarIndex();
fvb = LastValue(ValueWhen(NewDay, bi, 2)); // first bar of previous day
lvb = LastValue(ValueWhen(NewDay, bi, 1) - 1); // last bar one bar before the first bar of today

//one bin per tick of previous day's range
TickSize = 0.25; // set to the tick size for your market
bins = LastValue((TimeFrameGetPrice("H", inDaily, -1) - TimeFrameGetPrice("L", inDaily, -1)) / TickSize);

mx = PriceVolDistribution( H, L, V, bins, True, fvb, lvb );

GfxSetCoordsMode( 1 ); 

GfxSelectPen( colorRed ); 

bins = MxGetSize( mx, 0 ); 
for( i = 0; i < bins; i++ ) 
{ 
price = mx[ i ][ 0 ]; // price level 
relvolume = mx[ i ][ 1 ]; // relative volume 0..1 
relbar = relvolume * (lvb-fvb+1); 
GfxMoveTo( fvb, price ); 
GfxLineTo( fvb + relbar, price ); 
} 

Plot( C, "Price", colorDefault, styleBar );
SetChartOptions(0,chartShowArrows|chartShowDates); 

thanks and looking forward your help

i didn’t know of this function PriceVolDistrubution() yet.

yesterday I posted some code here: AFL to draw Trendline Between Previous day High and Previous day Low

the general idea for the value area is the same. I made some code just now. Can’t guarantee it is correct yet but getting close I would think. The code uses hard coded TickSize, so you need to adjust this yourself. I used 0.25 for ESmini futures. For stocks you will use TickSize = 0.01;

To calculate the “volume value area” I used a method described here: http://onlinelibrary.wiley.com/doi/10.1002/9781118659724.app1/pdf

the yellow lines correspond to the value area of the previous day. Dashed blue lines show the volume value area in the same day.

The value area can be changed using the parameter window.

// in reply to: http://forum.amibroker.com/t/how-to-get-the-most-traded-area-value-of-previous-day-intraday-data/2472
// code assumes your working with intraday data (e.g. 5min data)
// Value area calculation: http://onlinelibrary.wiley.com/doi/10.1002/9781118659724.app1/pdf
// !!!! TickSize is hardcoded in code. You need to adjust for according to contract specifics.
// E.M.Pottasch (10/2017)

TickSize = 0.25; // <<<<==== adjust yourself

zorder = Param( "Zorder", -1, -1, 1, 1 );
volumeValuearea = Param( "Volume Value area (%)", 0.7, 0, 1, 0.01 );

Title = Name() + "   Volume area (%): " + volumeValuearea * 100;

dn = DateNum();
newDay = dn != Ref( dn, -1 );
bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );

highOfDay = TimeFrameGetPrice( "H", inDaily );
lowOfDay = TimeFrameGetPrice( "L", inDaily );

lbx2 = ValueWhen( newDay, bi, 2 );
lbx1 = ValueWhen( newDay, bi, 1 );
lbx0 = ValueWhen( newDay, bi, 0 );

SetChartBkColor( ColorRGB( 0, 0, 0 ) );
Plot( Close, "Price", colorDefault, styleCandle, Null, Null, 0, 0, 1 );
Plot( newday, "", colorDarkBlue, styleHistogram | styleOwnScale | styleNoLabel | styleNoRescale, 0, 1, 0, 0, 5 );
Plot( highOfDay, "", colorGreen, styleLine, Null, Null, 0, 1, 1 );
Plot( lowOfDay, "", colorRed, styleLine, Null, Null, 0, 1, 1 );

GfxSetZOrder( zorder );
GfxSetCoordsMode( 1 );

cnt = 0; // count number of visible days

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

    if( IsEmpty( idx1 ) ) break;

    bins = int( ( highOfDay[ idx1 - 1 ] - lowOfDay[ idx1 - 1 ] ) / TickSize );
    mx = PriceVolDistribution( H, L, V, bins, False, idx2, idx1 );
    bins = MxGetSize( mx, 0 ); 
	//_trace( "bins: " + bins );
    
    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;
        GfxSelectPen( ColorRGB( 80, 0, 0 ), 1, 0 );
        GfxMoveTo( idx2, price );
        GfxLineTo( idx2 + relbar, price );

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

        totVol = totVol + relvolume;
    }

    // calculate Volume Value area
    mxih = mxil = mxVolBinIdx;
    tvol = mx[ mxVolBinIdx ][ 1 ];

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

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

        if( ( tvol / totVol ) > volumeValuearea ) break;
    }

    GfxSelectPen( ColorRGB( 0, 250, 250 ), 1, 1 );
    priceh = mx[ mxih ][ 0 ];
    pricel = mx[ mxil ][ 0 ];
    GfxMoveTo( idx2, priceh );
    GfxLineTo( idx1, priceh );
    GfxMoveTo( idx2, pricel );
    GfxLineTo( idx1, pricel );

    // draw into next day
    GfxSelectPen( ColorRGB( 250, 250, 0 ), 3, 0 );

    if( cnt > 0 )
    {
        GfxMoveTo( idx1, priceh );
        GfxLineTo( idx0, priceh );
        GfxMoveTo( idx1, pricel );
        GfxLineTo( idx0, pricel );
    }
    else
        if( cnt == 0 )
        {
            GfxMoveTo( idx1, priceh );
            GfxLineTo( BarCount, priceh );
            GfxMoveTo( idx1, pricel );
            GfxLineTo( BarCount, pricel );
        }

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

"cnt: " + cnt;

Good but How to get the value of idx1 high and idxlow

you mean the arrays which contain the valueAreaHigh and the valueAreaLow? You can simply save them into arrays, see example below:

// in reply to: http://forum.amibroker.com/t/how-to-get-the-most-traded-area-value-of-previous-day-intraday-data/2472
// code assumes your working with intraday data (e.g. 5min data)
// Value area calculation: http://onlinelibrary.wiley.com/doi/10.1002/9781118659724.app1/pdf
// !!!! TickSize is hardcoded in code. You need to adjust for according to contract specifics.
// E.M.Pottasch (10/2017)

TickSize = 0.25; // <<<<==== adjust yourself

volumeValuearea = Param( "Volume Value area (%)", 0.7, 0, 1, 0.01 );

Title = Name() + "   Volume area (%): " + volumeValuearea * 100;

dn = DateNum();
newDay = dn != Ref( dn, -1 );
bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );

valueHigh1 = valueLow1 = Null;
valueHigh0 = valueLow0 = Null;
highOfDay = TimeFrameGetPrice( "H", inDaily );
lowOfDay = TimeFrameGetPrice( "L", inDaily );

lbx2 = ValueWhen( newDay, bi, 2 );
lbx1 = ValueWhen( newDay, bi, 1 );
lbx0 = ValueWhen( newDay, bi, 0 );

SetChartBkColor( ColorRGB( 0, 0, 0 ) );
Plot( Close, "Price", colorDefault, styleCandle, Null, Null, 0, 0, 1 );
Plot( newday, "", colorDarkBlue, styleHistogram | styleOwnScale | styleNoLabel | styleNoRescale, 0, 1, 0, -2, 10 );
Plot( highOfDay, "", colorGreen, styleLine, Null, Null, 0, 0, 1 );
Plot( lowOfDay, "", colorRed, styleLine, Null, Null, 0, 0, 1 );

GfxSetZOrder( -4 );
GfxSetCoordsMode( 1 );

cnt = 0; // count number of visible days

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

    if( IsEmpty( idx1 ) ) break;

    bins = int( ( highOfDay[ idx1 - 1 ] - lowOfDay[ idx1 - 1 ] ) / TickSize );
    mx = PriceVolDistribution( H, L, V, bins, False, idx2, idx1 );
    bins = MxGetSize( mx, 0 );
    //_trace( "bins: " + bins );

    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;
        GfxSelectPen( ColorRGB( 80, 0, 0 ), 1, 0 );
        GfxMoveTo( idx2, price );
        GfxLineTo( idx2 + relbar, price );

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

        totVol = totVol + relvolume;
    }

    // calculate Volume Value area
    mxih = mxil = mxVolBinIdx;
    tvol = mx[ mxVolBinIdx ][ 1 ];

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

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

        if( ( tvol / totVol ) > volumeValuearea ) break;
    }

    //GfxSelectPen( ColorRGB( 0, 250, 250 ), 1, 1 );
    priceh = mx[ mxih ][ 0 ];
    pricel = mx[ mxil ][ 0 ];
    x1h = idx2;
    x2h = idx1;
    line = LineArray( x1h, priceh, x2h, priceh );
    valueHigh1 = IIf( line, line, valueHigh1 );
    line = LineArray( x1h, pricel, x2h, pricel );
    valueLow1 = IIf( line, line, valueLow1 );

    //GfxMoveTo( idx2, priceh );
    //GfxLineTo( idx1, priceh );
    //GfxMoveTo( idx2, pricel );
    //GfxLineTo( idx1, pricel );

    // draw into next day
    //GfxSelectPen( ColorRGB( 250, 250, 0 ), 3, 0 );

    if( cnt > 0 )
    {
        //GfxMoveTo( idx1, priceh );
        //GfxLineTo( idx0, priceh );
        //GfxMoveTo( idx1, pricel );
        //GfxLineTo( idx0, pricel );
        x1h = idx1;
        x2h = idx0;
        line = LineArray( x1h, priceh, x2h, priceh );
        valueHigh0 = IIf( line, line, valueHigh0 );
        line = LineArray( x1h, pricel, x2h, pricel );
        valueLow0 = IIf( line, line, valueLow0 );

    }
    else
        if( cnt == 0 )
        {
            //GfxMoveTo( idx1, priceh );
            //GfxLineTo( BarCount, priceh );
            //GfxMoveTo( idx1, pricel );
            //GfxLineTo( BarCount, pricel );
            x1h = idx2;
            x2h = Barcount;
            line = LineArray( x1h, priceh, x2h, priceh );
            valueHigh0 = IIf( line, line, valueHigh0 );
            line = LineArray( x1h, pricel, x2h, pricel );
            valueLow0 = IIf( line, line, valueLow0 );
        }

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

Plot( valueHigh1, "", ColorRGB( 0, 250, 250 ), styleDashed | styleNoRescale, Null, Null, 0, -3, 1 );
Plot( valueLow1, "", ColorRGB( 0, 250, 250 ), styleDashed | styleNoRescale, Null, Null, 0, -3, 1 );
Plot( valueHigh0, "", ColorRGB( 250, 250, 0 ), styleLine | styleNoRescale, Null, Null, 0, -3, 3 );
Plot( valueLow0, "", ColorRGB( 250, 250, 0 ), styleLine | styleNoRescale, Null, Null, 0, -3, 3 );
4 Likes

good one , but still struggling to get those values in exploration window

i do not really see why you want to use the exploration but when trying to make it you had me puzzled there :thinking: for a moment. I used static variables to solve it, however not sure why I need to use them.

I add the adjusted code because I changed the chart setting a bit, added few params.

1 remark: I hard coded the TickSize but you can also comment that out when you have set the TickSize in the Information window.

if anyone reading this (will also ask elsewhere). My capital letter A is not working in the Amibroker editor, it is working fine elsewhere. Anyone have this problem? Although I do not have the problem on my laptop so must be on my side but only seems to show up in the Amibroker editor.

// in reply to: http://forum.amibroker.com/t/how-to-get-the-most-traded-area-value-of-previous-day-intraday-data/2472
// code assumes your working with intraday data (e.g. 5min data)
// Value area calculation: http://onlinelibrary.wiley.com/doi/10.1002/9781118659724.app1/pdf
// !!!! TickSize is hardcoded in code. You need to adjust for, according to contract specifics.
// E.M.Pottasch (10/2017)

TickSize = 0.25; // <<<<==== adjust yourself

volumeValuearea = Param( "Volume Value area (%)", 0.7, 0, 1, 0.01 );
showVolume = ParamToggle( "Show Volume", "No|Yes", 0 );
showHL = ParamToggle( "Show High/Low boundaries", "No|Yes", 0 );
showVal1 = ParamToggle( "Show Value area inside same day", "No|Yes", 0 );
showVal0 = ParamToggle( "Show Value area projected into the next day", "No|Yes", 1 );

Title = Name() + "   Volume area (%): " + volumeValuearea * 100;

dn = DateNum();
newDay = dn != Ref( dn, -1 );
bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );

valueHigh1 = valueLow1 = Null;
valueHigh0 = valueLow0 = Null;
highOfDay = TimeFrameGetPrice( "H", inDaily );
lowOfDay = TimeFrameGetPrice( "L", inDaily );

lbx2 = ValueWhen( newDay, bi, 2 );
lbx1 = ValueWhen( newDay, bi, 1 );
lbx0 = ValueWhen( newDay, bi, 0 );

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

if( showHL )
{
    Plot( highOfDay, "", colorGreen, styleDots | styleNoLine | styleNoRescale, Null, Null, 0, 0, 1 );
    Plot( lowOfDay, "", colorRed, styleDots | styleNoLine | styleNoRescale, Null, Null, 0, 0, 1 );
}

GfxSetZOrder( -4 );
GfxSetCoordsMode( 1 );

cnt = 0; // count number of visible days

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

    if( IsEmpty( idx1 ) ) break;

    bins = int( ( highOfDay[ idx1 - 1 ] - lowOfDay[ idx1 - 1 ] ) / TickSize );
    mx = PriceVolDistribution( H, L, V, bins, False, idx2, idx1 );
    bins = MxGetSize( mx, 0 );
    //_trace( "bins: " + bins );

    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 )
        {
            GfxSelectPen( ColorRGB( 80, 0, 0 ), 1, 0 );
            GfxMoveTo( idx2, price );
            GfxLineTo( idx2 + relbar, price );
        }

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

        totVol = totVol + relvolume;
    }

    // calculate Volume Value area
    mxih = mxil = mxVolBinIdx;
    tvol = mx[ mxVolBinIdx ][ 1 ];

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

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

        if( ( tvol / totVol ) > volumeValuearea ) break;
    }

    priceh = mx[ mxih ][ 0 ];
    pricel = mx[ mxil ][ 0 ];
    x1 = idx2;
    x2 = idx1;
    line = LineArray( x1, priceh, x2, priceh );
    valueHigh1 = IIf( line, line, valueHigh1 );
    line = LineArray( x1, pricel, x2, pricel );
    valueLow1 = IIf( line, line, valueLow1 );

    // draw into next day
    if( cnt > 0 )
    {
        x1 = idx1;
        x2 = idx0;
        line = LineArray( x1, priceh, x2, priceh );
        valueHigh0 = IIf( line, line, valueHigh0 );
        line = LineArray( x1, pricel, x2, pricel );
        valueLow0 = IIf( line, line, valueLow0 );

    }
    else
        if( cnt == 0 )
        {
            x1 = idx2;
            x2 = BarCount - 1;
            line = LineArray( x1, priceh, x2, priceh );
            valueHigh0 = IIf( line, line, valueHigh0 );
            line = LineArray( x1, pricel, x2, pricel );
            valueLow0 = IIf( line, line, valueLow0 );
        }

    i = lbx1[ idx1 ];
    cnt++;

    StaticVarSet( "vh", valueHigh0 );
    StaticVarSet( "vl", valueLow0 );
}

if( showVal1 )
{
    Plot( valueHigh1, "", ColorRGB( 0, 250, 250 ), styleDots | styleNoLine | styleNoRescale, Null, Null, 0, -3, 1 );
    Plot( valueLow1, "", ColorRGB( 0, 250, 250 ), styleDots | styleNoLine | styleNoRescale, Null, Null, 0, -3, 1 );
}

if( showVal0 )
{
    Plot( valueHigh0, "", ColorRGB( 250, 250, 0 ), styleDots | styleNoLine | styleNoRescale, Null, Null, 0, -3, 1 );
    Plot( valueLow0, "", ColorRGB( 250, 250, 0 ), styleDots | styleNoLine | styleNoRescale, Null, Null, 0, -3, 1 );
    PlotOHLC( valueLow0, valueLow0, valueHigh0, valueHigh0, "", ColorRGB( 15, 15, 0 ), styleCloud | styleNoRescale, Null, Null, 0, -5, 1 );
}

Filter = Nz( StaticVarGet( "vh" ) ) OR Nz( StaticVarGet( "vl" ) );
AddColumn( Nz( StaticVarGet( "vh" ) ), "Upper Boundary Volume Value area", 1.2, colorWhite, colorRed, -1 );
AddColumn( Nz( StaticVarGet( "vl" ) ), "Lower Boundary Volume Value area", 1.2, colorWhite, colorGreen, -1 );
3 Likes

Awsome work emPottasch, we get the 70% area of previous day in current day, how to get the the value of day before yesterday in current day land in exploration
thanks:kissing_heart:

I think it would be best to make 2 separate arrays for that, unless of course in the next mail you send you want the day before that in the current day :smiley:

basically you define 2 arrays to hold this data and then in the section below “// draw into next day” you fill them up.

so you have to indicate the start and end index.

try yourself first

1 Like

will try my best thanks a ton empottasch

The reason is simple:

FirstVisibleValue() and LastVisibleValue() are chart functions not analysis functions (just like their name say “…Visible…”). In analysis both would return zero.

// Trace will return two times zero output for each value if applying in ANALYSIS.
// Reason: They are CHART functions. There is no visible area in Analysis.
// For analysis alternatively to static vars you may use Status() function codes.
bi = BarIndex();
_TRACEF( "fvb: %g, lvb: %g", FirstVisibleValue(bi), LastVisibleValue(bi));
2 Likes

thanks fx, didn’t know that, haven’t use the exploration myself much. Will adapt the code for that

added few things

  • the “point of control”
  • also when the volume area is set to 100% the blue lines should overlap with the day High/Low. It didnt do this always because the value area is calculated in steps of 2. Now I check if singles are left.
  • then added function so that exploration and indicator mode can be fed with different numbers. It works but exploration mode is slow maybe partially because in the function itself I also plot stuff. So this should be programmed differently in the next version :smiley: but indicator mode works fine
// in reply to: http://forum.amibroker.com/t/how-to-get-the-most-traded-area-value-of-previous-day-intraday-data/2472
// code assumes your working with intraday data (e.g. 5min data)
// Value area calculation: http://onlinelibrary.wiley.com/doi/10.1002/9781118659724.app1/pdf
// !!!! TickSize is hardcoded in code. You need to adjust for, according to contract specifics.
// E.M.Pottasch (10/2017)

TickSize = 0.25; // <<<<==== adjust yourself

volumeValuearea = Param( "Volume Value area (%)", 0.7, 0, 1, 0.01 );
showVolume = ParamToggle( "Show Volume", "No|Yes", 0 );
showHL = ParamToggle( "Show High/Low boundaries", "No|Yes", 0 );
showVal1 = ParamToggle( "Show Value area inside same day", "No|Yes", 0 );
showVal0 = ParamToggle( "Show Value area projected into the next day", "No|Yes", 1 );
showPOC = ParamToggle( "Show Point Of Control (POC)", "No|Yes", 1 );

dn = DateNum();
newDay = dn != Ref( dn, -1 );
bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );

valueHigh1 = valueLow1 = Null;
valueHigh0 = valueLow0 = Null;
pointOfControl = Null;
highOfDay = TimeFrameGetPrice( "H", inDaily );
lowOfDay = TimeFrameGetPrice( "L", inDaily );

lbx2 = ValueWhen( newDay, bi, 2 );
lbx1 = ValueWhen( newDay, bi, 1 );
lbx0 = ValueWhen( newDay, bi, 0 );

function calculateVolumeValueArea( fb, lb )
{
    GfxSetZOrder( -4 );
    GfxSetCoordsMode( 1 );

    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( ( highOfDay[ idx1 - 1 ] - lowOfDay[ idx1 - 1 ] ) / TickSize );
        mx = PriceVolDistribution( H, L, V, bins, False, idx2, idx1 );
        bins = MxGetSize( mx, 0 );
        //_trace( "bins: " + bins );

        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 )
            {
                GfxSelectPen( ColorRGB( 80, 0, 0 ), 1, 0 );
                GfxMoveTo( idx2, price );
                GfxLineTo( idx2 + relbar, price );
            }

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

            totVol = totVol + relvolume;
        }

        // calculate Volume Value area
        mxih = mxil = mxVolBinIdx;
        tvol = mx[ mxVolBinIdx ][ 1 ];
        pricePOC = mx[ mxVolBinIdx ][ 0 ];

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

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

            // handle uneven bars left
            if( mxih + 2 >= bins AND mxil - 2 < 0 )
            {
                if( mxih + 1 < bins )
                {
                    relvolumeh = mx[ mxih + 1 ][ 1 ];
                    mxih = mxih + 1;
                    tvol = tvol + relvolumeh;
                }

                if( mxil - 1 >= 0 )
                {
                    relvolumel = mx[ mxil - 1 ][ 1 ];
                    mxil = mxil - 1;
                    tvol = tvol + relvolumel;
                }
            }

            if( ( tvol / totVol ) > volumeValuearea ) break;
        }

        priceh = mx[ mxih ][ 0 ];
        pricel = mx[ mxil ][ 0 ];
        x1 = idx2;
        x2 = idx1;
        line = LineArray( x1, priceh, x2, priceh );
        valueHigh1 = IIf( line, line, valueHigh1 );
        line = LineArray( x1, pricel, x2, pricel );
        valueLow1 = IIf( line, line, valueLow1 );

        // draw into next day
        if( cnt > 0 )
        {
            x1 = idx1;
            x2 = idx0;
            line = LineArray( x1, priceh, x2, priceh );
            valueHigh0 = IIf( line, line, valueHigh0 );
            line = LineArray( x1, pricel, x2, pricel );
            valueLow0 = IIf( line, line, valueLow0 );

            line = LineArray( x1, pricePOC, x2, pricePOC );
            pointOfControl = IIf( line, line, pointOfControl );
        }
        else
            if( cnt == 0 )
            {
                x1 = idx2;
                x2 = BarCount - 1;
                line = LineArray( x1, priceh, x2, priceh );
                valueHigh0 = IIf( line, line, valueHigh0 );
                line = LineArray( x1, pricel, x2, pricel );
                valueLow0 = IIf( line, line, valueLow0 );

                line = LineArray( x1, pricePOC, x2, pricePOC );
                pointOfControl = IIf( line, line, pointOfControl );
            }

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

if( Status( "Action" ) == actionIndicator )
{
    Title = Name() + "   Volume area (%): " + volumeValuearea * 100;

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

    if( showHL )
    {
        Plot( highOfDay, "", colorGreen, styleDots | styleNoLine | styleNoRescale, Null, Null, 0, 0, 1 );
        Plot( lowOfDay, "", colorRed, styleDots | styleNoLine | styleNoRescale, Null, Null, 0, 0, 1 );
    }

    calculateVolumeValueArea( fvb, lvb );

    if( showVal1 )
    {
        Plot( valueHigh1, "", ColorRGB( 0, 250, 250 ), styleDots | styleNoLine | styleNoRescale, Null, Null, 0, -3, 1 );
        Plot( valueLow1, "", ColorRGB( 0, 250, 250 ), styleDots | styleNoLine | styleNoRescale, Null, Null, 0, -3, 1 );
    }

    if( showVal0 )
    {
        Plot( valueHigh0, "", ColorRGB( 250, 250, 0 ), styleDots | styleNoLine | styleNoRescale, Null, Null, 0, -3, 1 );
        Plot( valueLow0, "", ColorRGB( 250, 250, 0 ), styleDots | styleNoLine | styleNoRescale, Null, Null, 0, -3, 1 );
        PlotOHLC( valueLow0, valueLow0, valueHigh0, valueHigh0, "", ColorRGB( 10, 10, 0 ), styleCloud | styleNoRescale, Null, Null, 0, -5, 1 );
    }

    if( showPOC )
    {
        Plot( pointOfControl, "", ColorRGB( 250, 0, 250 ), styleDots | styleNoLine | styleNoRescale, Null, Null, 0, -3, 1 );
    }
}

if( Status( "Action" ) == actionExplore )
{
    calculateVolumeValueArea( 0, BarCount - 1 );

    Filter = Nz( valueHigh0 ) OR Nz( valueLow0 );
    AddColumn( Nz( valueHigh0 ), "Upper Boundary Volume Value area", 1.2, colorWhite, colorRed, -1 );
    AddColumn( Nz( valueLow0 ), "Lower Boundary Volume Value area", 1.2, colorWhite, colorGreen, -1 );
}
4 Likes

found a little error and added plotting of the volume in the last segment

the code between the if(cnt == 0)

can be replaced with:

            if( cnt == 0 )
            {
                x1 = idx1;
                x2 = BarCount - 1;
                line = LineArray( x1, priceh, x2, priceh );
                valueHigh0 = IIf( line, line, valueHigh0 );
                line = LineArray( x1, pricel, x2, pricel );
                valueLow0 = IIf( line, line, valueLow0 );

                line = LineArray( x1, pricePOC, x2, pricePOC );
                pointOfControl = IIf( line, line, pointOfControl );

                // draw volume current day
                if( showVolume )
                {
                    bins = int( ( highOfDay[ x2 ] - lowOfDay[ x2 ] ) / TickSize );
                    mx = PriceVolDistribution( H, L, V, bins, False, x1, x2 );
                    bins = MxGetSize( mx, 0 );
                    //_trace( "bins: " + bins + " x1: " + x1 + " x2: " + x2  );

                    dx = x2 - x1;

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

                        GfxSelectPen( ColorRGB( 80, 0, 0 ), 1, 0 );
                        GfxMoveTo( x1, price );
                        GfxLineTo( x1 + relbar, price );
                    }
                }
            }
1 Like

got a PM from Panos telling me about this: http://centerworldinvestment.blogspot.be/2016/04/re-amibroker-amibroker-6130-beta_27.html

so added that to the code.

Will leave it at that unless I get suggestions or mistakes and will correct for it. I do not really see why one needs an exploration with this but the way I solved it does not seem very good. So anyone who can do this more efficiently please show me how :slight_smile:

// in reply to: http://forum.amibroker.com/t/how-to-get-the-most-traded-area-value-of-previous-day-intraday-data/2472
// code assumes your working with intraday data (e.g. 5min data)
// Value area calculation: http://onlinelibrary.wiley.com/doi/10.1002/9781118659724.app1/pdf
// !!!! TickSize is hardcoded in code. You need to adjust for, according to contract specifics.
// E.M.Pottasch (10/2017)

// possible strategies (did not test any myself)
// - 80% rule: https://marketdelta.com/wp-content/uploads/Strategy-80PercentRule.pdf
// - 

// TickSize = 0.25; // <<<<==== adjust yourself

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 );
showVal1 = ParamToggle( "Show Value area inside same day", "No|Yes", 0 );
showVal0 = ParamToggle( "Show Value area projected into the next day", "No|Yes", 1 );
showPOC = ParamToggle( "Show Point Of Control (POC)", "No|Yes", 1 );
vai = Param( "Volume Value area Color Intensity", 15, 0, 254, 1 );

dn = DateNum();
newDay = dn != Ref( dn, -1 );
bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );
fvb = Max( 0, fvb ); 
lvb = Max( 0, lvb ); 

valueHigh1 = valueLow1 = Null;
valueHigh0 = valueLow0 = Null;
pointOfControl = Null;
highOfDay = TimeFrameGetPrice( "H", inDaily );
lowOfDay = TimeFrameGetPrice( "L", inDaily );

lbx2 = ValueWhen( newDay, bi, 2 );
lbx1 = ValueWhen( newDay, bi, 1 );
lbx0 = ValueWhen( newDay, bi, 0 );

function calculateVolumeValueArea( fb, lb )
{
    GfxSetZOrder( -4 );
    GfxSetCoordsMode( 1 );

    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( ( highOfDay[ idx1 - 1 ] - lowOfDay[ idx1 - 1 ] ) / TickSize );
        mx = PriceVolDistribution( H, L, V, bins, False, idx2, idx1 );
        //bins = MxGetSize( mx, 0 );
        //_trace( "bins: " + bins );

        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 )
            {
                GfxSelectPen( ColorRGB( 80, 0, 0 ), 1, 0 );
                GfxMoveTo( idx2, price );
                GfxLineTo( idx2 + relbar, price );
            }

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

            totVol = totVol + relvolume;
        }

        // calculate Volume Value area
        mxih = mxil = mxVolBinIdx;
        tvol = mx[ mxVolBinIdx ][ 1 ];
        pricePOC = mx[ mxVolBinIdx ][ 0 ];

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

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

            // handle uneven bars left
            if( mxih + 2 >= bins AND mxil - 2 < 0 )
            {
                if( mxih + 1 < bins )
                {
                    relvolumeh = mx[ mxih + 1 ][ 1 ];
                    mxih = mxih + 1;
                    tvol = tvol + relvolumeh;
                }

                if( mxil - 1 >= 0 )
                {
                    relvolumel = mx[ mxil - 1 ][ 1 ];
                    mxil = mxil - 1;
                    tvol = tvol + relvolumel;
                }
            }

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

        priceh = mx[ mxih ][ 0 ];
        pricel = mx[ mxil ][ 0 ];
        x1 = idx2;
        x2 = idx1;
        line = LineArray( x1, priceh, x2, priceh );
        valueHigh1 = IIf( line, line, valueHigh1 );
        line = LineArray( x1, pricel, x2, pricel );
        valueLow1 = IIf( line, line, valueLow1 );

        // draw into next day
        if( cnt > 0 )
        {
            x1 = idx1;
            x2 = idx0;
            line = LineArray( x1, priceh, x2, priceh );
            valueHigh0 = IIf( line, line, valueHigh0 );
            line = LineArray( x1, pricel, x2, pricel );
            valueLow0 = IIf( line, line, valueLow0 );

            line = LineArray( x1, pricePOC, x2, pricePOC );
            pointOfControl = IIf( line, line, pointOfControl );
        }
        else
            if( cnt == 0 )
            {
                x1 = idx1;
                x2 = BarCount - 1;
                line = LineArray( x1, priceh, x2, priceh );
                valueHigh0 = IIf( line, line, valueHigh0 );
                line = LineArray( x1, pricel, x2, pricel );
                valueLow0 = IIf( line, line, valueLow0 );

                line = LineArray( x1, pricePOC, x2, pricePOC );
                pointOfControl = IIf( line, line, pointOfControl );

                // draw volume current day
                if( showVolume )
                {
                    bins = int( ( highOfDay[ x2 ] - lowOfDay[ x2 ] ) / TickSize );
                    mx = PriceVolDistribution( H, L, V, bins, False, x1, x2 );
                    //bins = MxGetSize( mx, 0 );
                    //_trace( "bins: " + bins + " x1: " + x1 + " x2: " + x2  );

                    dx = x2 - x1;

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

                        GfxSelectPen( ColorRGB( 80, 0, 0 ), 1, 0 );
                        GfxMoveTo( x1, price );
                        GfxLineTo( x1 + relbar, price );
                    }
                }
            }

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

if( Status( "Action" ) == actionIndicator )
{
    Title = Name() + "   Volume area (%): " + volumeValuearea * 100;

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

    if( showHL )
    {
        Plot( highOfDay, "", colorGreen, styleDots | styleNoLine | styleNoRescale, Null, Null, 0, 0, 1 );
        Plot( lowOfDay, "", colorRed, styleDots | styleNoLine | styleNoRescale, Null, Null, 0, 0, 1 );
    }

    calculateVolumeValueArea( fvb, lvb );

    if( showVal1 )
    {
        Plot( valueHigh1, "", ColorRGB( 0, 250, 250 ), styleDots | styleNoLine | styleNoRescale, Null, Null, 0, -3, 1 );
        Plot( valueLow1, "", ColorRGB( 0, 250, 250 ), styleDots | styleNoLine | styleNoRescale, Null, Null, 0, -3, 1 );
    }

    if( showVal0 )
    {
        Plot( valueHigh0, "", ColorRGB( 250, 250, 0 ), styleDots | styleNoLine | styleNoRescale, Null, Null, 0, -3, 1 );
        Plot( valueLow0, "", ColorRGB( 250, 250, 0 ), styleDots | styleNoLine | styleNoRescale, Null, Null, 0, -3, 1 );
        PlotOHLC( valueLow0, valueLow0, valueHigh0, valueHigh0, "", ColorRGB( vai, vai, 0 ), styleCloud | styleNoRescale, Null, Null, 0, -5, 1 );
    }

    if( showPOC )
    {
        Plot( pointOfControl, "", ColorRGB( 250, 0, 250 ), styleDots | styleNoLine | styleNoRescale, Null, Null, 0, -3, 1 );
    }
}

if( Status( "Action" ) == actionExplore )
{
    calculateVolumeValueArea( 0, BarCount - 1 );

    Filter = Nz( valueHigh0 ) OR Nz( valueLow0 );
    AddColumn( Nz( valueHigh0 ), "Upper Boundary Volume Value area", 1.2, colorWhite, colorRed, -1 );
    AddColumn( Nz( valueLow0 ), "Lower Boundary Volume Value area", 1.2, colorWhite, colorGreen, -1 );
}
2 Likes

TickSize = 0.25; // <<<<==== adjust yourself

oh yeah I commented that out because I set this in the Information Window, see "Contract Specification"

contr