Running POC and VAH VAL

photo_2019-05-20_21-47-35

This is from ninja trader.
I want to recreate this stuff for amibroker.
but due to my very limited capabilities as a coder i'm not getting head start.
would love some help on this.

instead of getting POC as horizontal line at last value it is live plotting it along the market hours.

Have you used forum search?

So deriving from here and here.

bi = BarIndex();
dn = DateNum();
last_day = dn == LastValue(dn);
newday = dn != Ref( dn, -1);
fvb = FirstVisibleValue( bi );
lvb = LastVisibleValue( bi );
fbi = LastValue(ValueWhen(newday, bi));

function VariablePOC() {
	/// variable poc during last day	
	/// derived from example of AB manual
	/// @link https://www.amibroker.com/guide/afl/pricevoldistribution.html
	/// by fxshrat@gmail.com
	/// Commercial use prohibited!
	local i, n, mat, maxv, bins, price, relvolume, poc;
	poc = Null;	bins = 100;
	priceH = H;	priceL = L;	vol = Volume;	
	for( i = fvb; i <= lvb; i++ ) {
		
		if ( last_day[i] AND i >= fbi ) {
		
			mat = PriceVolDistribution( priceH, priceL, vol, bins, 0, fbi, i );

			maxv = 0;
			bins = MxGetSize( mat, 0 );
			for ( n = 0; n < bins; n++ ) {
				price = mat[ n ][ 0 ]; // price level
				relvolume = mat[ n ][ 1 ]; // relative volume 0..1	
				maxv = Max(maxv, relvolume);
			}

			// point of control
			for ( n = 0; n < bins; n++ ) {
				if ( maxv == mat[ n ][ 1 ] ) {
					poc[i] = mat[ n ][ 0 ]; // price level at highest vap									
					break;
				}
			}		
		}
	}
	return poc;
}

days = 1;
SetBarsRequired(days*inDaily/Max(1,Interval()));

poc = VariablePOC();

Plot( C, "Price", colorDefault, styleBar );
Plot( poc, "variable POC", colorYellow, styleStaircase );

41

7 Likes

And of course... Here is quicker version without need of nested loop.

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

function SelectedVariablePOC() {
	/// variable poc at selected day - INTRADAY(!) code
	/// @link https://forum.amibroker.com/t/running-poc-and-vah-val/12897/3
	/// by fxshrat@gmail.com
	/// Commercial use prohibited!
	local i, bi_cond, bins, fbi, lbi, lbp, mat;
	local mat_sort, priceH, priceL, vol, poc, rownum;
	poc = Null;	bins = 100;
	priceH = H;	priceL = L;	vol = V;	
	fbi = SelectedValue(ValueWhen(newday, bi));
	lbp = dn != Ref(dn, 1) OR bi == LastValue(bi);//FlagLastBarOfPeriod(235959);//
	lbi = SelectedValue(ValueWhen(lbp, bi, 0));	
	bi_cond = bi >= fbi AND bi <= lbi;	
	for ( i = fvb; i <= lvb; i++ ) {		
		if ( bi_cond[i] ) {		
			mat = PriceVolDistribution( priceH, priceL, vol, bins, 0, fbi, i );
			rownum = MxGetSize(mat, 0);
			mat_sort = MxSortRows(mat, True, 1);
			poc[i] = mat_sort[rownum-1][0];		
		}
	}
	return poc;
}

days = 1;
SetBarsRequired(days*inDaily/Max(1,Interval()));

poc = SelectedVariablePOC();

Plot( C, "Price", colorDefault, styleBar );
Plot( poc, "Variable POC", colorYellow, styleStaircase );

2


... and of course in another version one may connect all varPOCs of each day

44

12 Likes

thank you sir for your kind help.
i knew this must be possible in amibroker. but my very shallow knowledge of programming made me helpless.
Once again thank you

Dear members,

I was trying to use the same code and thinking if i can get POC at a particular time such as timenum()==094500. Is it possible if this can be done by passing lbi inn the function

Use ValueWhen and function of post #3.

/// Add function code of 
/// https://forum.amibroker.com/t/running-poc-and-vah-val/12897/3
/// HERE

days = 1;
SetBarsRequired(days*inDaily/Max(1,Interval()));

poc = SelectedVariablePOC();

tn_poc = ValueWhen(TimeNum() == 094500, poc);

Plot( C, "Price", colorDefault, styleBar );
Plot( poc, "Variable POC", colorYellow, styleStaircase );
Plot( tn_poc, "poc@09:45", colorRed);

6

2 Likes

Dear Sir;
I try to add VPA VPA plotting required from rightside
But this Working wrong
1
Would love some help on this
Thanks you

My code

_SECTION_BEGIN("VAP (left/right)");
GraphXSpace = 5;
SetChartOptions( 0, chartShowArrows | chartShowDates | styleNoLabel );
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 );
Title = Name() + " - {{INTERVAL}} - {{DATE}} - Open = " + NumToStr(O, 1.2) + ", High = " + NumToStr(H, 1.2) + ", Low = " + NumToStr(L, 1.2) + ", Close = " + NumToStr(C, 1.2) + " (" + WriteVal(ROC(C, 1), 1.2) + "%)"+ 
EncodeColor(colorCustom12) + "\n"+
"Use F12 and SHIFT+F12 to define range"; 

/*
	Authors: Anderson Wilson, Tomasz Janeczko, fxshrat 
		based on PriceVolDistribution demo written by Tomasz Janeczko
		
Volume-by-Price is an indicator that shows the amount of volume for a particular
price range,
The Volume-by-Price bars are horizontal and shown on the left side of the chart
to correspond 
with these price ranges. Bar colors indicate bear/bull volume

Use F12 and SHIFT+F12 to define range

Modifications: 
- plotting right AND left hand sided with percent width 
- loopless finding of max. volume
- Change from GfxSetOverlayMode to GfxSetZOrder
- Change to dynamic variables in loop for cleaner & better readable code  
- Added measure taking care of cases of H == L 
by fxshrat@gmail.com
https://forum.amibroker.com/t/vpa-plotting-required-from-rightside/13064/10
*/

bins = Param("Bins", 100, 3, 100, 1);  // no of line of volume bars
pRecHeight = Param("Rectangle Height", 0.45, 0.10, 1, 0.05);
pcnt_width = Param("Percent Width", 50, 1, 100, 1) / 100; 
z_order = Param("Z-order", -6, -6, 6, 1 );
left_sided = ParamToggle( "Side", "Right|Left", 0);
color1 = ParamColor( "Bull color", colorGreen);
color2 = ParamColor( "Bear color", colorRed);
color3 = ParamColor( "Total Vol. color", colorLightBlue);

bi = BarIndex();
fvb = BeginValue(bi);
lvb = EndValue(bi);
is_lastbi = lvb == LastValue(bi);
is_not_range = fvb == 0 AND is_lastbi;

GfxSetZOrder(z_order);

if ( left_sided ) { // if left sided
	if ( is_not_range ) {
		fvb = FirstVisibleValue( bi );
		lvb = LastVisibleValue( bi );
		x1_0 = Status("pxwidth");
		bar_range = x1_0;
		GfxSetCoordsMode( 2 );	
	} else {
		if ( fvb > 0 AND is_lastbi) 
			lvb = LastVisibleValue( bi );						
		x1_0 = lvb;
		bar_range = lvb-fvb;			
		GfxSetCoordsMode( 1 );		
	}	
} else { // if right sided
	if ( is_not_range ) {
		fvb = FirstVisibleValue( bi );
		lvb = LastVisibleValue( bi );					
	} 	
	x1_0 = fvb;	
	bar_range = lvb-fvb;
	GfxSetCoordsMode( 1 );
}
bar_range *= pcnt_width;
	
fvb = Max(0, fvb);
lvb = Max(0, lvb);

BullBearZone = (High - Low) / 3;
bullbar = C > (High - BullBearZone);
bearbar = C < (Low + BullBearZone);

priceH = IIf(H==L, H+1e-5, H);
mx0 = PriceVolDistribution(priceH, L, V, bins, absolute = True, fvb, lvb);
mx1 = PriceVolDistribution(priceH, L, IIf(bullbar, V, 0), bins, absolute, fvb, lvb);
mx2 = PriceVolDistribution(priceH, L, IIf(bearbar, V, 0), bins, absolute, fvb, lvb);

for ( n = 0; n <= 2; n++ ) {
	mx = VarGet("mx"+n);
	if ( typeof( mx ) == "matrix" )
		VarSet("bins"+n, MxGetSize(mx, 0));
	else
		VarSet("bins"+n, 1);
}

if( bins0 > 1 && bins0 == bins1 && bins0 == bins2 ) {

	// find max volume
	mat_sort = MxSortRows(mx0, False, 1);				
	MaxVolume = mat_sort[0][1];		
	
	// rectangle height
	RecHeight = (mx0[ 1 ][ 0 ] - mx0[ 0 ][ 0 ]) / 2 * pRecHeight;
	
	x2_0 = x1_0;	
	for ( i = 0; i < bins0; i++ ) {
		price = mx0[ i ][ 0 ]; // price level		
		// volumes
		absVolume1 = mx1[ i ][ 1 ];
		absVolume2 = mx2[ i ][ 1 ];
		absVolume3 = mx0[ i ][ 1 ];	
		//
		VolAcum = 0;
		for ( n = 1; n <= 2; n++ )	{
			absVolume = VarGet("absVolume"+n);
			VolAcum += absVolume;
			VarSet("relvolume"+n, absVolume / MaxVolume);						
		}
		relvolume3 = (absVolume3 - VolAcum) / MaxVolume;
		//
		for ( n = 1; n <= 3; n++ )	{
			relvolume = VarGet("relvolume"+n);
			VarSet("relbar" + n, relvolume * bar_range);
		}			
		//
		y1 = price + RecHeight;
		y2 = price - RecHeight; 
		//		
		if ( left_sided ) { // if left sided
			for ( n = 1; n <= 3; n++ ) {
				VarSet( "x2_"+n, VarGet("x1_"+(n-1)));		
				VarSet( "x1_"+n, VarGet("x2_"+n) - VarGet("relbar"+n));
			}
		} else { // if right sided
			for ( n = 1; n <= 3; n++ ) {
				VarSet( "x1_"+n, VarGet("x2_"+(n-1)));		
				VarSet( "x2_"+n, VarGet("x1_"+n) + VarGet("relbar"+n));
			}
		}
		for ( n = 1; n <= 3; n++ )
			GfxFillSolidRect(VarGet("x1_"+n), y1, VarGet("x2_"+n), y2, VarGet("color"+n));
	}
}

//////////////////////PRunning POC and VAH VAL//////////////////////////////////////////

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

function SelectedVariablePOC() {
	/// variable poc at selected day - INTRADAY(!) code
	/// @link https://forum.amibroker.com/t/running-poc-and-vah-val/12897/3
	/// by fxshrat@gmail.com
	/// Commercial use prohibited!
	local i, bi_cond, bins, fbi, lbi, lbp, mat;
	local mat_sort, priceH, priceL, vol, poc, rownum;
	poc = Null;	bins = 100;
	priceH = H;	priceL = L;	vol = V;	
	fbi = SelectedValue(ValueWhen(newday, bi));
	lbp = dn != Ref(dn, 1) OR bi == LastValue(bi);//FlagLastBarOfPeriod(235959);//
	lbi = SelectedValue(ValueWhen(lbp, bi, 0));	
	bi_cond = bi >= fbi AND bi <= lbi;	
	for ( i = fvb; i <= lvb; i++ ) {		
		if ( bi_cond[i] ) {		
			mat = PriceVolDistribution( priceH, priceL, vol, bins, 0, fbi, i );
			rownum = MxGetSize(mat, 0);
			mat_sort = MxSortRows(mat, True, 1);
			poc[i] = mat_sort[rownum-1][0];		
		}
	}
	return poc;
}

days = 1;
SetBarsRequired(days*inDaily/Max(1,Interval()));

poc = SelectedVariablePOC();

tn_poc = ValueWhen(TimeNum() == 094500, poc);

Plot( poc, "Variable POC", colorYellow, styleStaircase );
Plot( tn_poc, "poc@09:45", colorRed);

_SECTION_END();


2
i try to daily but when check with Tradingview will wrong :sweat_smile:

Carefully read the code comments. So not just copy&pasting.

Once again... you have set weekly interval for intraday sessions code (to get variable POC from some start of day to some end of same day).

The 2nd copied code is not supposed to get constant POC for n-number of days, weeks, months.
Please try to understand that code.

To get constant POC for mx0 of first copied code you may do like this.

// point of control
mat_sort = MxSortRows(mx0, False, 1);				
poc = mat_sort[0][0];	
maxv = mat_sort[0][1];	// Vol. at POC
2 Likes

Thank you, I will checking again