Bank of England - Open Data

This tutorial was originally published on DataCareer.

In this tutorial we will retrieve data from the Bank of England's Statistical Interactive Database (IADB) using Python 3. Please take a look at the following sites to get a feel for what kind of data is available:


As an example, we will take a look at the fixed mortgage interest rates in the UK since the year 2000. The full description of the series is:

Monthly interest rate of UK monetary financial institutions (excl. Central Bank) sterling 2, 3, 5 and 10 year (75% LTV) fixed rate mortgage to households (in percent) not seasonally adjusted.

We will use Python to (re)construct the following example URL and retrieve the data. If you click on this link, it will download the data:,IUMBV37,IUMBV42,IUMBV45&CSVF=TN&UsingCodes=Y&VPD=Y&VFD=N

In the above URL, we used CSV as the data format. It is possible to download data in other formats, like XML, HTML and Excel. In this tutorial we will work with Pandas, so we prefer to retrieve the data in CSV format. Please note that the API takes the following parameters:

Parameter name Required format Example
Datefrom DD/MON/YYYY (mandatory parameter) 01/Feb/2006
Dateto DD/MON/YYYY or "now" (mandatory parameter) 01/Oct/2007
SeriesCodes Comma separated list of full series codes (mandatory parameter) LPMAUZI,LPMAVAA
UsingCodes "Y" (mandatory parameter) Y
CSVF "TT", "TN", "CT" or "CN" (mandatory parameter) TN
VPD "Y" or "N" (optional parameter) Y


As always, let's start with importing some packages we will use for this exercise.

First, we define the URL endpoint:

Secondly, we define the parameters of our request:

We can use the requests package to construct the URL with the dictionary of parameters:

The URL that was constructed by the requests package is:

We can use Pandas' read_csv function to load the data. The function takes a file (or an URL) as an argument. We already downloaded the data (as bytes), so we can pass it with 'io.BytesIO'.

This already looks pretty good. But, notice the value of '0' at '29 Feb 2000' for the 10-year mortgage rate ('IUMBV45'), which looks suspicious. Please inspect the series df['IUMBV45'] and you'll see there are missing values between index 116 to 174, represented by '..' (two dots). Strangely, at index 157, there is a value. If you are working in Jupyter Notebooks and cannot print the entire series to your screen, you can use this little hack (converting the series to string)


Can you see the series? Let's continue the inspection.

Checking the DataFrame's information, it seems there are three things that need to be done:

  1. Convert the 'DATE' column to 'datetime' format (now it is 'object)
  2. Set 'DATE' to be the index (now it is a 'RangeIndex')
  3. Convert the 10-year mortgage rate 'IUMBV45' to be numeric

Series 'IUMBV45' is of type "object" (and not "float64") because of the missing values are represented by '..' (two dots). We can convert it to float64 and will empty all the cells with dots by setting the parameter errors='coerce' in Pandas 'to_numeric' function.

This looks better, the dates are the index now and there are 167 values left for 'IUMBV45'. Remember the value of '0' at '29 Feb 2000'? Let's see if there are any other dates with a value of '0'.

It happens only once. For sake of simplicity of this tutorial, let's not worry too much about it and just get rid of this one occurrence. (We did report this anomaly to the Bank of England, so perhaps it is not there anymore when you run the code).

Excellent, the data does seem to make sense. Longer mortgages normally have higher rates than shorter ones. The mean interest rates from 2, 3, 5 and 10 mortgages (left to right respectively) are indeed increasing, which we expected. To conclude, let's visualize this data.

Hopefully you enjoyed this tutorial!