The Volatility of Volatility for Stocks and Crypto, Part 2

Cross-random correlation for modeling stocks & crypto

NTTP
10 min readMay 11, 2024
El Segundo: “the second”… “A significant center of the oil and aerospace industries in Southern California.” (Courtesy of Wikipedia)

In this, the next part of our series on the volatility-of-volatility for stocks and crypto currency price modeling, we get into another interesting feature of the Heston model for stochvol: The correlation of two random processes, and the possibly surprising results of this interaction when we put it into the model.

Get the latest Excel file for this article here:

https://github.com/diffent/excel/blob/main/volofvol2H.xlsx

Hint: go there and then click Raw, and it should download.

The two random processes in question are: one process which generates the main daily return “buzz” (in our example asset: with mean zero and standard deviation of 1%) and another process which generates the volatility of volatility, at mean 1 and some standard deviation that is tunable. We went through examples of adjusting this vol-of-vol in our prior article; though, to be sure, we did not adjust it to any particular target yet.

Review

Recall in our previous article that we used a random generator in Excel that produced standard normal scatter points (mean 0, stdev 1) and then modified it so that the stdev was itself a random value, getting something along the lines of:

=NORMINV(RAND( ), 0, 1 * NORMINV(RAND( ),1,0.2))

The outer random generator (bold) in this example has mean 0 and stdev 1, and the inner (which modifies this “outer’s” standard deviation) has mean 1 and stdev 0.2. The constants [0, 1, 1, 0.2] are just for the particular made-up example asset here; they are not universal. The inner random generator is the baseline “volatility of volatility” modification. In our sheet, we had split this up into separate steps to make it easier to see and trace (as this article is an exposition rather than a compact formula coding exercise), and to add necessary guardrails so that the stdev arguments don’t go out of the range that Excel supports.

The two instances of RAND( ) here are not coupled in any way in our prior example, except in that they access the same random generator in Excel (which, if sticklers want to point sticks, is a very loose coupling… but not enough to notice for this coarse analysis). The two random processes are practically decoupled and should show a correlation coefficient of close to zero as we increase the point count beyond 1000. We might see a slight bit of correlation at our 1000 day point count due to chance. Per a previous article of ours, random does not imply “un-patterned,” but it does imply that any patterns found are not predictive of the future.

For this article, we first show how we can generate randomly correlated distributions of a normal shape (shaped like normal distributions if we look at one variable at a time… at the two marginal distributions in fancier terminology… equivalent to a special case of a two variable elliptical distribution maybe?) via this interesting method from the website noted below this image:

Snapshot from https://www.bogleheads.org/forum/viewtopic.php?t=285724

We do this math on sheet randcorr of this new Excel example file:

Example of two random distributions negatively correlated

Columns A and B are standard normal random columns (uncorrelated) and columns D and E are the partially correlated results of applying the above formulation.

You can look into the reference we link above for how this works; the formulas that we put into Excel to do this are in columns D and E of that sheet.

To control the target correlation in this example, one can adjust the value in K2. It’s good to experiment with this value to get an intuitive feel for what is going on by looking at the dot plot as you change the target correlation. Negative values are allowed and in fact encouraged, though you may want to keep the numbers between -1 and 1, since that is the range of typically computed correlation coefficients.

Example of two random distributions positively correlated

Additionally, we re-compute the correlation of the generated points using the CORREL function in N2 to check our math. TDD, Test-Driven-Development type of thing. You should get close to the input value you had set in K2 as long as you keep K2 within the range -1 to 1 (inclusive).

The Linkback

Next, go to sheet randcorrWithFeedback.

randcorrWithFeedback sheet

What we do here is use the second of the correlated random number sequences (column E, the vol-of-vol) to modify (by multiplication) the standard deviation in the formula of the first of the correlated sequences (column D). At first glance, this sounds like it might lead to circular reference formulas in Excel (infinite loops), but it does not. You can examine the above plain pseudocode formulas for generating linked sequences to convince yourself that Y (in the snapshot) does not depend on X.

We can also show this using the Excel trace precedence arrows:

Same snapshot as prior, with trace precedence on for E2

Clicking on cell E2 (the vol-of-vol) and tracing the precedence, we can see that E2 does not depend on D2 (the return itself). Therefore, we can use E2’s output in the D2 formula.

The formula in D2 has its standard deviation (nominally 1 in our example, as defined in H2) multiplied by the particular (partly correlated) random value generated at the same row in column E.

Formula in D2 sheet randCorrWithFeedback, showing which cells it depends upon directly via standard Excel cell highlighting when formula editing is active.

The resulting distribution is now an emergent phenomenon that turns out better than it seems like it would, what with all this randomness of randomness going on. You can see this by examining the histograms above.

Instead of merely being able to control the tail fatness (kurtosis) of our returns distribution as we did in the prior article (by adjusting the stochvol stdev), we can now also “put our thumb on the scale” of the skew of the distribution (bullish or bearish) by adjusting the target correlation between the two random series (K2 in this sheet).

Here is another screen shot of a “returns” distribution resulting from setting target correlation to a negative value. Note the negative skew now, versus the above histograms:

Since these are randomized results, every time you refresh the sheet, you will often get often notably different histograms back. Such is the nature of a stochastic generating process.

Now all we need to do is use these generated returns back in Sheet1 column A, instead of computing them the simpler way that we did in the prior article.

Notice that the column A rows are one row down in sheet 1 versus this randcorrWithFeedback sheet.

We set A3 in Sheet 1 to reach across to this new sub-calcuation sheet using this formula:

=randcorrWithFeedback!D2

Then we copy the formula down column A to get our 1000 points.

We deleted some cell contents that are no longer relevant in Sheet1 to avoid confusion, since we are computing the random returns now on the other sheet.

The multiplying up of returns into prices happens automatically (since we had already set it up for the last article) and we can observe the resulting price chart.

Here are a couple example runs of the price generator with the exact same settings on sheet randcorrWithFeedback:

Animation: Some sheet refreshes of our price series assembled from the newly generated returns. Model parameters are the same for all of these animation frames. Visible changes are due to refreshing the sheet. Each refresh results in a new random price walk driven by our new method of generating returns.

Much like in our earlier article, due to the random nature of this model — and even though we have not changed any model parameters — we get different time series curves for each sheet recalculation.

To get a new price chart at the same settings, you can just recalc the sheet.

Typically something like Shift F9, F9… something about F9… ChatGPT can probably tell you. There used to be a menu item for this, but where they moved it to, I don’t know. You can also type recalc into the light bulb icon’d “Tell me what you want to do” field in Excel, and it will find it; but this search does not tell you the precise short cut key, at least in the version of Excel that I am running. Get that A.I. updated, Redmond.

Since we are using two sheets now, you might need to do the old “force recalc all sheets”: Ctrl Alt F9 per some online docs… but you’ll figure it out.

It is slightly inconvenient to go to another sheet when we want to change parameters, but we leave the file this way for now to avoid too much confusion. It is easy as a refinement to move the controlling parameters to the first sheet. The point here is to show how relatively simple this concept is (so far)… though it is getting a little intricate.

Remember that the price chart you see in one sheet refresh cycle is merely one of many possible —

(“infinitely” possible; since we are dealing with bit limited floating point values here, it is practically infinite, though not actually infinite)

— paths that this random generator can generate. We will need to aggregate a bunch of these random paths to get price/probability forecasts like we do in our app MCarloRisk3D. One path at a time is not enough to tell us much besides the qualitative character of these paths: “smooth, jagged, momentum-like, oscillatory, return-to-mean-like, bullish, bearish,” et cetera.

But we are not done with modeling individual paths yet, so we will defer this aggregation to a future article in this series.

The reveal

Equations snap-shotted from [Quantstart] (our annotations). Oh, and the Column 3 we mention above refers to the worksheet from the prior article (column C no doubt, if you count your columns by letters). There is a sometimes-used feature in Excel to flip the column indicators to numbers instead of letters:

https://www.indeed.com/career-advice/career-development/numbers-for-columns-in-excel

Again to avoid too much confusion, we have revealed the second equation of the Heston model at the end of this article instead of the beginning… to try to show how it relates to the first equation, and to show what we just did in Excel. We cross out the terms that we have not modeled yet. A variable which does not appear in these two equations directly is Greek letter rho (⍴), the correlation coefficient between the two random generating functions. This is the “target correl” in our sheet randcorrWithFeedback (which the user can change in K2 of that sheet).

Leftovers

One thing that we have not crossed out is the constant coefficient 𝛏 (xi), a difficult symbol to draw if you haven’t learned cursive (and sometimes even if you have and aren’t Greek) and also easily confused with a cursive cap E. As yet, we have not been too concerned with the particular constants of this model since we are not tuning to any real circumstance yet; but 𝛏 seems to correspond to the constant vol-of-vol value in sheet randcorrWithFeedback, cell J2. It merely scales the stochastic dW normally distributed “buzz” to the right of it.

Other nomenclature (if not clarified, at least illuminated)

The two dW symbols are in honor of Norbert himself:

As the Wiki notes, this is also known as Brownian motion which some of us may recall from high school biology class with respect to microscopic particle movements noted in fluids (or was it physics?). Might it then be instead notated by dB? “It might, rabbit, it might.” But dB is also used for deciBels and change in magnetic field… maybe other things? So many concepts, so few letters. We’ll just follow the common usage of dW here.

All that the dW terms represent in our discrete time math here (in concept) is: bumping something randomly, using random values sampled from a [standard] normal distribution. In our Excel, we just model the pure dW terms by NORMINV(RAND( ), mean_constant, stdev_constant). And of course the two dW terms in the above equation snapshot are coupled by the correlation method described in this article.

Of note

There is still at least a square root sign or two that we are ignoring. But even if we don’t include more of the Heston model concepts, our model seems to represent observed daily return distribution shapes better than the normal distribution does. We can use one of our software packages MCarloRisk or MCarloRisk3D to examine returns distributions directly and see the non-normality of returns over a period of time:

Actual (static) daily returns distribution of TSLA in a recent time period. Positive skew, fat tails.
Animation of repeated sheet refreshes of our new method for generating the returns distribution (sheet = randcorrWithFeedback). Model parameters are not changed between refreshes. This is for a constant set of model parameters, yet there is so much variation. It is the random nature of this distribution generator that is causing some results to be left skewed, some right skewed… and other shape variations. Note: The smooth-ish animation between stable distributions is done by Excel’s graphics code and is unrelated to this method.

Summary

By introducing the correlation between the main random generator process and the vol-of-vol generator, we can now start to control skewness (bullish/bearishness) in addition to kurtosis (tail fatness) of our artificially generated returns. Our fake asset returns are now far from the idealized normal distribution of returns that is sometimes assumed, and they are not constantly distributed over all price paths generated.

Why, might you ask, go to all this trouble to model skew and tail fatness? Surely there are easier ways. This is perhaps a good question for Heston & Co. themselves. But we are not finished modeling yet, so let us suspend our disbelief temporarily. And remember that every time we recalculate the spreadsheet, the distribution changes due to all the randomness fed into it. This is not a static-in-time distribution model.

Next up!

Stay tuned to this Medium channel for the next model enhancement that will get us even closer to the Heston model of stochastic volatility! The term with kappa in it (𝜅) in the 2nd of the above equations (which we crossed out in bright green) seems ripe for the picking now.

Update May 18 2024: Part 3 is now online!

https://medium.com/@nttp/the-volatility-of-volatility-part-3-5caf88195afd

Reference

We snap-shotted the Heston model equations and got other ideas from this fine exposition. This author does it all in one fell swoop, but his descriptions are good if you want more info:

[Quantstart] Heston Stochastic Volatility Model with Euler Discretisation in C++, https://www.quantstart.com/articles/Heston-Stochastic-Volatility-Model-with-Euler-Discretisation-in-C/

--

--