Probability Cone

Let's say an Option expires at a future date (on a candle yet to form beyond the Barcount - 1) for which there is no Quote yet and I want to visualize the probable range of the security assuming constant volatility as per the selected bar. Below is an attempt which obviously throws Error 10: Array subscript out of range whenever a bar is selected that provoke the lines to be plotted beyond Barcount - 1.

_SECTION_BEGIN( "Probability Cone" );
	 SetChartOptions( 0, chartShowDates );
	 
	 PrcFld = ParamField( "Price Field", 3 );
	 chPrcFld = ParamToggle( "Choice Field Hi-Lo", "Field|H-L", 0 );
	 //volTyp = ParamList( "Vol. Type", "GARCH|VIX|IV", 2 );
	 vol = 0.10; //Assumed Volatility (ideally based on volTyp)
	 intrvl = Param( "No. of days ahead", 5, 1, 252 );
	 stdPer = Param( "Std. Dev.", 2, 1, 5, 0.5 );	 

	 bi = SelectedValue( BarIndex() );
	 
	 stdDev = Null;
	 u = Null;
	 d = Null;
	 ctr = 0;
	 
	 if( ( bi + intrvl ) <= Status( "lastvisiblebar" ) )
	 {
		 for( i = bi; i <= bi + intrvl; i++ )
		 {
			 stdDev[ i ] = stdPer * ( PrcFld[ bi ] * vol[ bi ] * sqrt( ctr / 365 ) );
			 if( chPrcFld )
			 {
				 u[ i ] = H[ bi ] + stdDev[ i ];
				 d[ i ] = L[ bi ] - stdDev[ i ];
			 }
			 else
			 {
				 u[ i ] = PrcFld[ bi ] + stdDev[ i ];
				 d[ i ] = PrcFld[ bi ] - stdDev[ i ];
			 }
			 ctr++;
		 }
	 }
	 
	 Plot( C, "", colorDefault, styleCandle );
	 Plot( u, "", colorBlue, styleLine | styleNoLabel | styleNoRescale, Null, Null, 0, 1, 2 );
	 Plot( d, "", colorYellow, styleLine | styleNoLabel | styleNoRescale, Null, Null, 0, 1, 2 );
	 
	 //PlotText( NumToStr( u[ bi + intrvl ], 1.2 ), bi + intrvl + 2, u[ bi + intrvl ], colorBlue );
	 //PlotText( NumToStr( d[ bi + intrvl ], 1.2 ), bi + intrvl + 2, d[ bi + intrvl ], colorYellow );
	 
	 Title = "{{DATE}} C " + C;
_SECTION_END();

Is there a solution for this?

Thank you!

1 Like

Probability%20cone

This is what I have.

4 Likes

Any hint @Anthony how you identify and plot on a future date? And is my StdDev calculation correct?

You can use XShift feature of Plot() function or graphics functions. Practical example how to plot in future using Plot() function is given here Predicting future indicator values without having inverse function

1 Like

Thank you Tomasz for sharing the link. Learned a new technique!

However, the challenge that I am attempting to apprehend is to pinpoint (Lookup for) the expiration date ahead of the end of arrays. How do I find the number of bars between a future expiration date (for which a candle is yet to form) and a selected bar?

In the above image shared by Anthony, I am wondering how the "Expiration Date: 10/5/2018" was drawn?

The expiry date of all contracts is known before hand whether they're monthlies / weeklies or LT.
Given that you know the expiry, AFAIK all options calculations require it anyway, using dummy/random values is wrong.

Subtract Last Traded daytime or selected bar as you wish from the Expiry date using
https://www.amibroker.com/guide/afl/datetimediff.html

The time difference returned in seconds can be divided "appropriately" according to current "Interval" using the Interval built-in variable.

BarsToExp = DateTimeDiff( StrToDateTime( "2018-Sep-27 16:00:00" ), LastValue( DateTime() ))  / Interval();

So now you know the number of bars till expiry. Code does not count current bar, add 1 if you want to.

1 Like

In the above image shared by Anthony, I am wondering how the "Expiration Date: 10/5/2018" was drawn?

Use GFX functions to draw whatever you want.
http://www.amibroker.com/guide/h_lowlevelgfx.html

Sorry Clark its not viable as it does not account the weekends.

That also depends on what Option pricing model you are using, all necessarily don't need to account weekends.

If you want to, you can calculate that, and then you maybe posting a next question about the holidays.
Unless you build a custom blackbox like those running by institutions it will be tough and with lack of info in your opening post it becomes all the more hard.

It has nothing to do with Option pricing model. My OP was on how to identify Barindex of future dates such that I could procure a for loop and that's all I am looking for.

Thank you

Just multiply by (5/7) and you will get good approximation of trading days.

1 Like

Is there a way in AFL to get hold of these dates of future bars on which a candle is yet to form?

hmm

These are monday...friday dates in the future. You can just generate them.

@Lennon
Loop not needed & for cone use GfxArc.
1111

@Lennon - because you can't do calculations using future (blank) bars, you can solve this issue in (at least) two ways:

  1. First option is described here: http://www.amibroker.com/kb/2015/01/14/drawing-line-extensions-on-future-bars-using-afl/

The calculations past the very last bar are not possible, because that would require a longer array than the one we work on.

Therefore – we need the following approach:

  1. first we shift the input back (to the left) by N bars, so the real input data would occupy earlier part of the array and we would have extra bars at the end for the calculation of extended arrays

  2. now we calculate the position of arrays on such shifted

  3. shift the displayed output forwards with XSHIFT functionality of Plot function (so the calculated extensions would get aligned onto the blank bars as a result).

  1. Second option - you can use matrix to store the results of your calculations and Gfx functions to plot/draw the results in the blank bars area.

I have modified and expanded your initial code - now it utilizes matrix and Gfx functions:

Probability%20Cone%202

_SECTION_BEGIN( "Probability Cone" );

// By Lennon 
// Modified and expanded by Miłosz Mazurkiewicz
/// @link https://forum.amibroker.com/t/probability-cone/8110/15

PF = ParamField( "Price Field", 3 );
CF = ParamToggle( "Choice Field Hi-Lo", "Field|H-L", 0 );
Vol = Param( "Assumed Volatility", 0.1, 0.01, 5, 0.01 ); //(ideally based on volTyp)
FutureBars = Param( "Number of days ahead", 30, 1, 252 );
StdPer = Param( "Standard Deviation", 2, 1, 5, 0.1 );
DE = Param("Days to expiry", 22, 0, 150, 1); 

SetChartOptions( 0, chartShowArrows | chartShowDates, chartGridMiddle, 0, 0, FutureBars );
bi = BarIndex();
Point = LastValue( bi ); // Point = SelectedValue(bi);
LVB = status( "lastvisiblebar" );
PF = PF[Point];
StMatrix = Matrix( 2, FutureBars );

for( i = 0; i < FutureBars; i++ )
{
    StdDev = StdPer *  PF * Vol * sqrt( i / 365 ) ;

    if( CF )
    {
        StMatrix[0][i] = H[ Point ] + stdDev;
        StMatrix[1][i] = L[ Point ] - stdDev;
    }
    else
    {
        StMatrix[0][i] = PF + stdDev;
        StMatrix[1][i] = PF - stdDev;
    }
}

GfxSetCoordsMode( 1 );
GfxMoveTo( Point, PF[Point] );
GfxSelectFont( "ArialNarrow", 7, 400 );
ColorUp = ColorBlend( colorbrightGreen, colorWhite, 0.9 );
ColorDown = ColorBlend( colorSkyblue, colorWhite, 0.2 );

for( i = 0; i < FutureBars; i++ )
{

    y1 = StMatrix[0][i];
    y2 = StMatrix[1][i];

    GfxSelectPen( colorGreen, 2 );
    GfxSelectSolidBrush( colorGreen );
    GfxLineTo( Point + i, y1 );
    GfxCircle( Point + i, y1, -2 );
	
    if( i % 2 == 0 and  i != 0 )  PlotTextSetFont( "" + Prec( y1, 2 ), "Arial Narrow", 8,  Point + i, y1, colorBlack, ColorUp, 20 );
    
    if (i == DE) GfxSelectPen( colorOrange, 2 );
 
    else GfxSelectPen( colorLightGrey, 1 );
    
    GfxLineTo( Point + i, y2 );

    if( i % 2 == 0 AND i != 0 )  PlotText( "" + Prec( y2, 2 ), Point + i, y2, colorBlack, ColorDown, -20 );

    GfxSelectSolidBrush( colorRed );
    GfxSelectPen( colorRed, 2 );
    GfxCircle( Point + i, y2, -2 );
    GfxLineTo( Max( Point + i - 1, Point ), StMatrix[1][Max( i - 1, 0 )] );
    GfxMoveTo( Point + i, y1 );
    
    if( i > LVB - Point ) break;
}

GfxSelectPen( colorGold, 2 );
GfxMoveTo( Point, PF[Point] );
GfxLineTo( Point + i - 1, PF[Point] );
Plot( C, "", colorDefault, styleCandle );

_SECTION_END();

David, you can take it from here - modify the code and add another functionalities :slight_smile:


BTW @Anthony it's a pity, that you haven't decided to shed light on your custom solution. Of course no body is expecting from you showing the code (if you don't want to), but writing just a few words describing how it works, could be very useful to other users trying to build similar solutions on their own.

26 Likes

No words @Milosz :blossom::blossom::blossom:

1 Like

..."because you can't do calculations using future (blank) bars,".......that's why I said loop not needed.

stdDev = stdPer * ( Close[ bi ] * vol * sqrt( intrvl / 365 ) );

& for visual representation use GfxArc
333aaa
As usual great code @Milosz :tulip::hibiscus:

@Fossil ... the arc (section of ellipse) ≠ parabola (at least when we talk about 'real' ellipses with finite dimensions).

@Milosz - great contribution - thanks.

3 Likes

Thanks for the nice words @Lennon, @Fossil and @Tomasz

@fossil - this is just a simple example which can be modified in many different ways. For example I can see, that in your case the numbers are overlapping. You can easily avoid that if you modify the two similar lines in the code this way:

if( i % 3 == 0 and  i != 0 )  PlotTextSetFont( "" + Prec( y1, 2 ), "Arial Narrow", 8,  Point + i, y1, colorViolet, colorDefault, 20 );

Now the numbers will be displayed every third (not every second) point and there will be no outstanding background colors. For instance:

Probability%20Cone%203


This line inside a loop:

if( i > LVB - Point ) break;

Prevents Gfx functions from drawing on the right margin area.


If someone uses AB 6.29, the chart might look different from those above (some elements are thinner) because of the (temporary) changes implemented in GfxSelectPen() in the latest beta.

BTW: This 39'th line can be deleted - it's not necessary:

GfxSelectFont( "ArialNarrow", 7, 400 );
2 Likes

Hi, I have been going through this and thanks for everyone's input.

I believe that the plot is wrong and attach my work to demonstrate this.

Volatility%20Cone%20Comparison

Using the example above, it really needs to take into account weekends, and in a perfect world public holidays, otherwise the whole concept of using it as a visual tool to marry the underlying's price with it possible position at expiry does not make sense.

The example above uses,
Last Bar 12th Feb 2019
Expiry Date 28th Mar 2019
Number of Days Remaining 44
Number of Weekends Days 12
Number of Trading Days (Excluding Public Holidays) 32

Tomasz' suggestion of taking 5/7 would work as an approximation if you were looking for an expiry date way into the future (90+), but I would suggest
for expiries of 45 days or less, this is going to be too clunky.
It actually depends on the number of days to expiry, the day of the week of the expiry date and the day of the week of the last bar, to get it exact.

In the example above, the volatility cone should end where the green dotted line is.

Hope this helps.