Quick Volatility Contraction Pattern Calculation (VCP) Using Trendline Studies and AFL

I found this great conversation about "Drawing Multiple Lines using GetAsyncKeyState" and thought it would make using VCPs a little easier.

There is only one problem with the code, maybe someone can help me? With this code and also the original code from @PanoS I always have to double click until the line starts to draw. This activates the "Range Maker" which is slightly irritating. Am I doing something wrong? (use the latest AmiBroker version 6.35.1)

/**
Calculate Volatility Contractions
by @PatrickDoblerCH, 22.09.2020

Acknowledgement:
Basic idea by RocketPower

Most of the code is from PanoS and Lennon: https://forum.amibroker.com/t/drawing-multiple-lines-using-getasynckeystate-or-any-better-method/12007/18
*/

_SECTION_BEGIN( "Measure volatility contractions" ); // Using GetAsyncKeyState()
nMM = 6; //Max no. of MM lines

bi = BarIndex();
dt = DateTime();
t=0;
pct="";
duration = "";
titel_new = "";
MouseBtn = GetCursorMouseButtons();
LeftJustClkd = MouseBtn & 8;
LeftClkDownRlsd = MouseBtn & 9;
MiddleClkd = MouseBtn & 4;
chartId = Name() + Interval();

x = GetCursorXPosition( 0 );
y = GetCursorYPosition( 0 );

if( GetAsyncKeyState( 48 ) < 0 OR GetAsyncKeyState( 96 ) < 0 AND MiddleClkd )
{
	StaticVarRemove( "x1*" );
	StaticVarRemove( "y1*" );
	StaticVarRemove( "x2*" );
	StaticVarRemove( "y2*" );
	StaticVarRemove( "pct_t*" );
}

for( i = 49; i <= 48 + nMM; i++ )
{
	riMM = i - 48;	
	DigitPressed = GetAsyncKeyState( i ) < 0 || GetAsyncKeyState( i + 48 ) < 0;
	if( DigitPressed )
	{
		// This elegant technique shared by @Milosz
		if( LeftJustClkd )
		{
			StaticVarSet( "x1" + chartId + riMM, x, 0 );
			StaticVarSet( "y1" + chartId + riMM, y, 0 );
			//StaticVarSet( "y1_start" + chartId + riMM, bi, 0 );
			
		}	
		if( LeftClkDownRlsd )
		{
			StaticVarSet( "x2" + chartId + riMM, x, 0 );
			StaticVarSet( "y2" + chartId + riMM, y, 0 );		
		}
		if( MiddleClkd )
		{
			StaticVarRemove( "x1" + chartId + riMM );
			StaticVarRemove( "y1" + chartId + riMM );
			StaticVarRemove( "x2" + chartId + riMM );
			StaticVarRemove( "y2" + chartId + riMM );
			StaticVarRemove( "pct_t" + chartId + riMM );
		}
		RequestMouseMoveRefresh();
	}
}

GfxSetBkMode( 1 );
GfxSetCoordsMode( 1 ); // mode = 1 - bar / price mode where X is expressed in bar index and Y is expressed in price.

for( i = 1; i <= nMM; i++ )
{
	x1 = Lookup( bi, StaticVarGet( "x1" + chartId + i ) );
	y1 = StaticVarGet( "y1" + chartId + i );
	x2 = Lookup( bi, StaticVarGet( "x2" + chartId + i ) );
	y2 = StaticVarGet( "y2" + chartId + i );
	if( x1 != 0 AND x2 != 0 )
	{
		t++;
		GfxSelectPen( colorGrey50, 2, 1 );
		GfxMoveTo( x1, y1 );		GfxLineTo( x2, y2 ); 	// Diagonal line
		
		GfxSelectFont( "Courier New", 9.5, 700 );
		pct0 = NumToStr( abs(y2/y1-1)*100, 1.0, False );
		pct1 = NumToStr( abs(y2/y1-1)*100, 1.1, False );
		GfxTextOut( "   T"+NumToStr( i, 1.0 )+": " +pct1 , x1 , y1 );
		StaticVarSetText("pct_t" + chartId + i, pct0, false);
	}
}


//lasttrendline = Lookup( dt, StaticVarGet( "x2" + chartId + t ) );

//iterate through total number of contractions (t)
for( i = 1; i <= t; i++ )
{
	//append the latest contraction % into a string
	pct += StaticVarGetText("pct_t" + chartId + i) + "/";
}

//set date
startT1 = Lookup( dt, StaticVarGet( "x1" + chartId + 1 ) );

if ( t != 0 )
{
	//calculate from start to most recent date. result is rounded in weeks
	duration = Round(DateTimeDiff(LastValue(dt), startT1)/3600/24/7);
	titel_new = "= " + duration  + "W  " + StrTrim(pct, "/") + "  "+  t + "T";
}

Title = "VCP Profile " + titel_new;
_SECTION_END();

vcp1

vcp2

8 Likes

This is gold @paddy! Thanks for evolving this tool into something that is 100x easier to use!

I don't really ever have time to code deeply, so I rig up something quick and deal with the quirks. So I'm especially grateful when people take my code and make it what I wish it could be!

Take care!
Mike

2 Likes

Hi @paddy i run your code, and in my PC seems that there is not problem at all, i do NOT have to double click.
Are you sure that you first press the button on the keyboard and the you draw the line?

In general, I wish there was a feature to disable those vertical bars from showing up. I never, ever use them.

@Tomasz, is this possible and if not, can it be an option in a future update?

Thanks!
Mike

Thanks for testing! Interesting, which version are you running?
Yes, I’m sure. For example, number 0+middleBtnClick also works instantly (deleting everything). I also tested clicking middleButton and then leftClick. That also works like a double click


@rocketPower: I was also searching for this to disable. This is what I found.

Hi @rocketPower i have to remind you that is all ready exist read the forum

So @paddy according to the above post what you need is to insert one more line to your code

SetChartOptions( 1, chartHideQuoteMarker, chartGridMiddle, 0, 0, 0 );

Hi @rocketPower while you are here at this moment
is it possible to answer please to the main problem that @paddy has at this moment... i test hes AFL and i do NOT have to double click to draw the line.
what about you

Thanks @PanoS, I accidentally replied on the old thread, but yeah that works!

For some reason the green bar still shows up after a few clicks, but I can deal!

Strange :roll_eyes:

This line doesn’t change anything for me. Even by changing "Vert. quote marker" in Parameter the range markers in green and red still appear while double clicking.

I also tried to open a new blank chart without any other indicators on it than OHLC.

Actually I realized the green/red bars still show up, but I only need to click once to make the chart frame the active one, and with this feature turned off, you don't get the thick lavender bar.

Then I click and hold to start dragging the the contraction line and it shows up. So doing this I don't get any annoynig vertical lines when measuring VCPs.

1 Like

I have found a pretty ugly workaround. But of course it does not explain why a double click is needed on my computer. (@rocketPower is it also the same on yours?)

By pressing CTRL+F12 you can delete the vertical range makers. So, I send those strokes here:

		if( LeftJustClkd )
		{
			WSHShell = CreateObject( "WScript.Shell" );
            WSHShell.Sendkeys( "^{F12}" );
			StaticVarSet( "x1" + chartId + riMM, x, 0 );
			StaticVarSet( "y1" + chartId + riMM, y, 0 );
		}	
1 Like

Hi paddy,

thanks a lot for this awesome solution. As for your double click issue, I think it happens on my system too. I use AB version 6.30.5 and I do this:

  1. Press <1> + Double left mouse click => "T1: 0.0" appears next to it and the thin green vertical line
  2. Left mouse click and hold to draw the line to the desired spot.

Deleting the VCPs works just with one mouse click + number 0 or 1 or ...

The way you did try s wrong.

Just hold the number and then draw the line with one click from point A to B

1 Like

That's strange. At first I tried lots of variations, the one I used was the only one which worked. So I tried yours again, nothing happened, I cleared my test chart and added the price code and this VCP code, still nothing. I tried the normal numbers on the keyboard and the ones on the numpad, I also switched the keyboard language to English. And I also looked in "Tools/ Preferences" and the charts parameters: I found no option which would suggest a different behavior.

I tried it in this way:

  1. Press number on keyboard
  2. Left mouse click in the chart at point A
  3. Left mouse click in the chart at point B

And I also tried it by holding the left mouse button in step 2 and moving to B and releasing the button at B. Both version resulted in no line and no text.
I tried this with unlocked CAP, but even if I lock CAP it still works with the numbers on the keyboard, even though writing something creates other characters.

Is there some option I am missing or should I really do a new installation on a test machine?

Same, i've installed the official release version 6.30.5 too, had the same behavior. But if you know it is not so bad.

I love what you have done with this. I tried it out and overall it seems to work great. The only problem I have run into, which I am having a problem troubleshooting, is that it causes several parts of my interpretation window outputs to duplicate. Im not sure why that is happening. If I take this version out and put @rocketpower original back in, the interpretation window is fine, no duplicates. Ive tried modifying your title line but that doesn't take care of it. Ill keep playing with it though because I really like your process.

1 Like

That's strange, where did you put this code in your overall code? I didn't have this effect.

Vertical line (blue) is the SELECTOR line. It appears after single click and can be turned OFF in the Preferences.
Green/Red lines are RANGE MARKERS. Everything is as always described in great detail in the Users manual http://www.amibroker.com/guide/h_charting.html
They only appear when you DOUBLE CLICK, but you don't need to double click on chart because SINGLE CLICK does formula execution and ALL formulas work with single click.

I wrote about that dozens of times, but really you can NOT use AmiBroker correctly, if, at minimum, you don't read entire Tutorial section of the manual: http://www.amibroker.com/guide/tutorial.html

@rocketPower All I did was from my chart, pulled up the chart settings and hit "delete indicator" to remove the original one VCP that you wrote and then just drag and dropped @paddy 's version onto the chart. Haven't had a chance to work on it but plan too again here soon. Not sure why it was causing duplicates to the interpretation window. It may have something to do with some of the modifications I made to your interpretation output is all I can think.

Maybe you need to rightclick on you chart, then "Edit formula..." and delete the content which wasn't deleted. This can happen if the indicator you add to the chart have no proper SECTION defined.

1 Like

I'll check that out @paddy . Thanks for the suggestion.