Starting on 7 November 2019, the Bank of England‘s Inflation Report became the Monetary Policy Report. This quarterly publication communicates economic analysis and inflation projections that the Monetary Policy Committee uses to make its interest rate decisions.

Since 1996 the Bank of England (BoE) inflation forecast has been published as a probability distribution and presented in what is now known as * ‘the fan chart’*.

The first fan charts that were published by the BoE can be found in its Inflation Report-February 1996. A digital copy of the printed report (which used to be sold for £3!) can be found here (see page 48 for the charts).

In this post, we will review the ideas behind the fan charts, as well as details on how they are constructed and interpreted. We will use the fanchart library to plot them with Python!

## Motivation

The BoE introduced the fan charts aiming to communicate a more accurate representation of their forecast for medium term inflation. In particular, the charts have two key objectives:

- To convey the
in their forecasts. This is, to focus attention on the*uncertainty*, rather than only on small changes to the central projection.*the forecast distribution* - To promote discussion of the risks to the economic outlook, and thus contribute to a wider debate about economic policy. Fan charts help to make it clear that monetary policy is about
instead of knowing the exact rate of inflation in two years time.*making decisions*

## Choice of the Two-Piece Normal

Historical observations showed that inflation outcomes were **not symmetrically dispersed around a central value**, with the values closer to the centre being more likely than those further away. This led to the choice of the **two-piece normal distribution**, which can capture asymmetry through a skewness parameter, for the forecast model.

As we know, the probability density function (pdf) of the two-piece normal (see my previous post for more details) is defined as $$

s(x) := s\left(x; \mu,\sigma_1,\sigma_2\right) =

\begin{cases}

\dfrac{2}{\sigma_1+\sigma_2}f\left(\dfrac{x-\mu}{\sigma_1}\right), \qquad \mbox{if } x < \mu, \\

\dfrac{2}{\sigma_1+\sigma_2}f\left(\dfrac{x-\mu}{\sigma_2}\right), \qquad \mbox{if } x \geq \mu, \\

\end{cases}

$$ where $f: \mathbb{R} \mapsto \mathbb{R}_{+}$ is the pdf of the standard normal distribution. However, the Bank of England uses the following re-parametrisation:$$

\sigma_1 = \dfrac{\sigma}{\sqrt{1-\gamma}} ; \qquad

\sigma_2 = \dfrac{\sigma}{\sqrt{1+\gamma}},

$$ where $\sigma >0$ and $\gamma \in (-1, 1)$. Thus, the pdf of the two-piece normal can be written as$$

s(x) := s\left(x; \mu,\sigma,\gamma\right) =

\begin{cases}

\dfrac{A}{\sqrt{2\pi}\sigma} \exp \left\{ -\dfrac{1-\gamma}{2\sigma^2} \left[(x-\mu)^2\right] \right\}, \qquad \mbox{if } x < \mu, \\

\dfrac{A}{\sqrt{2\pi}\sigma} \exp \left\{ -\dfrac{1+\gamma}{2\sigma^2} \left[(x-\mu)^2\right] \right\}, \qquad \mbox{if } x \geq \mu, \\

\end{cases}

$$ where $A = \dfrac{2}{\frac{1}{\sqrt{1-\gamma}}+\frac{1}{\sqrt{1+\gamma}}}$.

So, in order to derive the forecast distribution for each quarter ahed, three parameters need to be estimated:

- $\mu$ : a measure of the central tendency for inflation
- $\sigma$ : a view on the degree of uncertainty
- $\gamma$ : a view on the balance of the risks, to get a measure of the skew.

Once these parameters are set, the two-piece normal is completely defined. BoE publishes these parameters as part of its quarterly report as:

- Mode
- Uncertainty
- Skewness

You can download all the data related to the fan charts by using the “Download the chart slides and data (ZIP)” option in the Monetary Policy Report website.

## Python Implementation

We will use the fanchart library to reproduce the fan charts. This library contains a copy of the BoE data and parameters (already in the format required by the functions) as of November 2019.

`from fanchart.plot import *`

### Quarter Fan Chart

First, we plot a variant of the fan charts which uses only the projection associated to a single quarter.

For this purpose, we will use the function ** fan_single** which provides functionality for two kinds of charts, namely the probability density function (pdf) and the cumulative distribution function (cdf).

In order to use the ** fan_single** function, we need to provide:

- The parameters $\mu, \sigma, \gamma$ (loc, sigma, and gamma) for the two-piece distribution corresponding to the quarterly projection.
- A set of probabilities which define the bands of the chart
- The kind of plot, namely ‘pdf’ or ‘cdf ‘

For illustration purposes, we use the parameters corresponding to the projection for 2020-10-01. You can find parameters corresponding to other dates here. Remember that the parameters are called mode, uncertainty, and skewness by the BoE.

```
prob = [0.05, 0.20, 0.35, 0.65,0.80, 0.95]
fan_single(loc=1.51, sigma=1.34, gamma=0.0, p=prob, kind='pdf');
fan_single(loc=1.51, sigma=1.34, gamma=0.0, p=prob, kind='cdf');
```

```
prob = np.arange(0.10, 1, 0.05)
fan_single(loc=1.51, sigma=1.34, gamma=0.0, p=prob, kind='pdf');
fan_single(loc=1.51, sigma=1.34, gamma=0.0, p=prob, kind='cdf');
```

### Projection Fan Chart

Now, we will plot the fan chart that illustrates the entire projection ahead. For this we will use the function** fan** which requires:

- A data frame containing the parameters $\mu, \sigma, \gamma$ (loc, sigma, and gamma) for every quarter in the projection. You can load the parameters corresponding to the Nov-2019 Report from the fanchart library.
- A data frame with the observed historical inflation. This serves to produce the solid line before the fan part. You can load the historical data corresponding to the Nov-2019 Report from the fanchart library.
- A set of probabilities which define the bands of the chart.

```
history = load_boe_history()
parameters = load_boe_parameters()
probs = [0.05, 0.20, 0.35, 0.65,0.80, 0.95]
fan(data=parameters, p=probs, historic=history[history.Date >='2015'].iloc[::3,]);
```

```
probs = np.arange(0.10, 1, 0.05)
fan(data=parameters, p=probs, historic=history[history.Date >= '2015'].iloc[::3,]);
```

Note that at any particular point in the forecast period (which has a grey background) the shading of the bands gets lighter as the probability of inflation lying further away from the central projection decreases.

Besides, as predictions become increasingly uncertain over time, these forecast ranges spread out, creating the distinctive”fan” or wedge shapes which originated the “fan chart” term.

### Surface Fan Chart

As we mentioned, uncertainty increases over time so we can think of looking at the whole density function over time. This is done in the following three-dimensional chart, which includes the probability density on the z-axis.

The shading of this chart emphasises that there is much less certainty about the outcome two/three years ahead than about the outcome one quarter ahead.

We can eve even create an animation which allows us to look at the forecast in detail.

## Further Reading

- Two-Piece Normal
- A Brief History of the two-piece normal
- The family of two-piece distributions with R implementation
- Fan Charts in R

Hello Dialid thank you for this very interesting analyses! Could you please provide some application areas for the mentioned two-piece (normal) family of distributions ? For example, whether they would be reasonably applied in analyzing asset returns and simulating portfolio returns under different market regimes. Also, could you provide a python code overview behind the single/projection fan charts functions ? Would be helpful to understand how these are generated. Thanks!

Sincerely,

Nikola

Hi Nikola,

Many thanks for your suggestions. I am working on some more entries with applications to econometrics 🙂 but in the meanwhile I suggest to take a look at the paper Bayesian Regression Analysis with Scale Mixtures of Normals by Carmen Fernández and Mark F. J. Steel

in Econometric Theory. Regarding the code, take a look at the Demo of my package ‘fanchart’ which is open source 🙂 https://gist.github.com/quantgirluk/64bdf810a6063296e30759a228a3dbc5

Best regards!

Dialid