PriceVolDistribution Notice in Analysis

I get a Notice when trying to run Explore in Analysis. There is no output. The problem seems to have something to do with a matrix in my Volume at Price code. As far as I can tell, my code closely resembles the code on the AB website at https://www.amibroker.com/guide/afl/pricevoldistribution.html. This code also gives me a Notice in Analysis. Here is the Notice for my code: Notice

My VAP code:

// VAP 
_SECTION_BEGIN( "Volume At Price (VAP)" );
showVAP = ParamToggle( "Show VAP", "No|Yes", 1 );
showMonth = ParamToggle( "Show Month/Year VAP", "No|Yes", 0 );
nbins = Param( "Bins", 15, 3, 100, 1 );
pRecHeight = 0.9; //Param( "Rectangle Height", 0.90, 0.10, 1, 0.05 );
fontSize = 7; //Param( "Font Size", 7, 3, 15, 1 );
fontColor = colorWhite; // ParamColor( "Font Color", colorWhite );
bi = BarIndex();
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi ); 
// Classify volume into three bins - top, middle and bottom thirds
BullBearZone = ( H - L ) / 3;
bullbar = C > ( H - BullBearZone );
bearbar = C < ( L + BullBearZone );
// mx = [row 0][col 0]
// price levels in first column [0][0] and relative volume at that level in second column [0][1]
// https://www.amibroker.com/guide/afl/pricevoldistribution.html
mx = PriceVolDistribution( H, L, V, nbins, True, fvb, lvb ); // Total vol all bars
mx1 = PriceVolDistribution( H, L, IIf( bullbar, V, 0 ), nbins, True, fvb, lvb ); // Tot vol in upper 1/3 of candle
mx2 = PriceVolDistribution( H, L, IIf( bearbar, V, 0 ), nbins, True, fvb, lvb ); // Tot vol in lower 1/3 of candle
// PlotVAPOverlay
nbins = MxGetSize( mx, 0 );
nbins1 = MxGetSize( mx1, 0 );
nbins2 = MxGetSize( mx2, 0 );
GfxSetOverlayMode( 1 );
GfxSetCoordsMode( 1 );
if( showVAP )
{
	if( nbins > 1 && nbins == nbins1 && nbins == nbins2 )
	{
		MaxVolume = mx[ 0 ][ 1 ]; // Column = 1
		
		// find max volume in col 1 and associated price in col 0
		for( i = 1; i < nbins; i++ )
		{
			if( mx[ i ][ 1 ] > MaxVolume )
			{
				MaxVolume = mx[ i ][ 1 ]; // Volume for that bin 1...
				MaxVolume = IIf( MaxVolume > 0, MaxVolume, 0.001 );
			}
		}

		// rectangle height
		RecHeight = ( mx[ 1 ][ 0 ] - mx[ 0 ][ 0 ] ) / 2 * pRecHeight;
		GfxSelectFont( "Arial", fontSize ); // Change the text size here

		for( i = 0; i < nbins; i++ )
		{
			// mx1 = Bull volume - close in upper 1/3 of candle
			price = mx1[ i ][ 0 ]; // price level
			absVolume = mx1[ i ][ 1 ];
			absVolume = IIf( absVolume > 0, absVolume, 0.001 );
			VolAcum = absVolume;
			relvolume1 = absVolume / MaxVolume;
			relbar = relvolume1 * ( lvb - fvb + 1 );
			// upper left ner of the rectangle.
			x1 = fvb;
			y1 = price + RecHeight;
			// lower right ner of the rectangle.
			x2 = fvb + relbar;
			y2 = price - RecHeight;
			bullColor = ColorBlend( colorSeaGreen, GetChartBkColor(), 0.6 );
			GfxFillSolidRect( x1, y1, x2, y2, bullColor );
			GfxSetBkColor( bullColor );
			GfxSetTextColor( colorWhite );
			GfxTextOut( NumToStr( round( relvolume1 * 100 ), 2.0 ) + "%", x1, y1 );

			// mx2 = Bear volume - close in lower third of candle
			absVolume = mx2[ i ][ 1 ];
			VolAcum += absVolume;
			relvolume2 = absVolume / MaxVolume;
			relbar2 = relvolume2 * ( lvb - fvb + 1 );
			x1 = x2;
			x2 = x1 + relbar2;
			bearColor = ColorBlend( colorCustom16, GetChartBkColor(), 0.6 );
			GfxFillSolidRect( x1, y1, x2, y2, bearColor );
			GfxSetBkColor( bearColor );
			GfxSetTextColor( colorWhite );
			GfxTextOut( NumToStr( round( relvolume2 * 100 ), 2.0 ) + "%", x1, y1 );

			// mx = All Bars
			absVolume = mx[ i ][ 1 ];
			relvolume3 = ( absVolume - VolAcum ) / MaxVolume;
			if( relvolume3 > 0 ) // Remove zeros as this interferes with Price below
			{
				relbar3 = relvolume3 * ( lvb - fvb + 1 );
				x1 = x2;
				x2 = x1 + relbar3;
				midColor = ColorBlend( colorGrey40, GetChartBkColor(), 0.2 );
				GfxFillSolidRect( x1, y1, x2, y2, midColor );
				GfxSetBkColor( midColor );
				GfxSetTextColor( colorWhite );
				GfxTextOut( NumToStr( round( relvolume3 * 100 ), 2.0 ) + "%", x1, y1 );
			}
			// Output Price at the end of the histogram
			GfxSetBkColor( colorBlack );
			GfxSetTextColor( colorAqua );
			GfxTextOut( NumToStr( round( Price / 100 ), 2.0 ), x2 + 1, y1 );
			
			// Plot Support & Resistance lines
			a = round( relvolume1 * 100 );
			b = round( relvolume2 * 100 );
			d = round( relvolume3 * 100 );
			Diff = IIf( a >= 0 AND b >= 0, abs( a - b ), 0 );
			if( Diff >= 0 AND Diff <=2 )		
				Plot( Price, "", colorDarkOliveGreen, styleDashed | styleNoLabel );
			if( a + b + d > 98 )
			{
				pctMTZ = round( ( ( C - Price ) / Price ) * 100 );
				Plot( Price, "\nVAP MTZ(" + pctMTZ + "%)", colorAqua, styleDashed, Null, Null, 2, -1, 1 );
			}
		}
	}
}
if( showMonth )
{
	segments = IIf( Interval() == inDaily, Month(), Year() );
	segments = segments != Ref(segments , -1 ); 
	PlotVAPOverlayA( segments, nbins * 2, 95, ColorBlend( colorLightBlue, colorBlack, 0.5 ), 4 );
}
// VAP Interpretation
printf( "<b>\nVOLUME AT PRICE (VAP)</b>" );
printf( "\nVAP shows total volume of trading that occurred at given price level. VAP is calculated from data bars that are currently visible.\nThe longest bars show the most traded zone.\nBars are divided into thirds acding to the Close in lower, mid and upper thirds.\n" );
_SECTION_END();

I would greatly appreciate any insights / solutions.

(Using AB v6.39.1 on a PC with an AMD Ryzen 16 core with 16GB RAM and 64 bit software.)

Your code should have code Elements specific to Exploration for AA/Explore output like Filter / AddColumn() etc to display the output correctly.

GFX / Plot / PlotVAP... are all chart specific.

FirstVisibleValue() and LastVisibleValue() also behave differently in AA and Charts so you should be aware of that.

As to the MX notice, i am not sure, but it is not an "error" so if you have correct Explore Elements like Filter=1 and AddColumn() etc then you will still get some output otherwise it is Blank.

You can add the following lines at the end and you will see what I mean.

Filter =1;
AddColumn( C, "C", 1.2);

-->

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


As for creating exploration follow the manual...
www.amibroker.com/guide/h_exploration.html


You do not need loop to get maximum

mat_sort = MxSortRows(mx, False, 1);				
MaxVolume = mat_sort[0][1];	

Sorry, I forgot to mention that the code is part of a larger AFL file that does have a Filter.

empottasch: Thanks for the shorter version of finding MaxVolume. And thanks a stack for pointing me in the right direction. I changed the offending code to:

bi = BarIndex(); fvb = BeginValue( bi ); lvb = EndValue( bi ); if( fvb == 0 && lvb == LastValue( bi ) ) { fvb = BeginValue( lvb - 149 ); // 149 is the default number of bars on my chart }

It now works fine and does not give me a warning in Analysis. I can also double click to set the begin and end values to a specific range.

Note: I have 180 bars on the chart by default (30 blank) and subtract 149 from the LastValue of the BarIndex (bi) to get a provisional VAP display. I can then double click on the chart to set the beginning (fvb) and end (lvb) of the VAP range, or double click on the blank space to the right of the candles to reset it to include all visible candles.

bursaware: You need to set filter and addcolumn conditions to the end of your AFL, for example:

Filter = 1;
AddColumn( H, "H", 1.2 );
AddColumn( L, "L", 1.2 );

Then in the Analysis window you can select to further filter by watchlist and dates.

1 Like

I am not empottasch.
And it wasn't empottasch posting shorter version.

There is no bursaware in this thread.

Please read carefully

1 Like

My apologies - and thanks a lot. I really appreciate your input.

This topic was automatically closed 100 days after the last reply. New replies are no longer allowed.