Exchange Rates¶
In [6]:
# Import simple warning to ignore
import warnings
warnings.simplefilter('ignore', FutureWarning)
# import pandas
from pandas import *
# Import the plotting modules and set default format
import matplotlib
matplotlib.rcParams['axes.grid'] = True # show gridlines by default
# Show plots in the notepad
%matplotlib inline
import matplotlib.pyplot as plt
from matplotlib.ticker import (MultipleLocator, FormatStrFormatter,
AutoMinorLocator)
import matplotlib.dates as mdates
# Import LXML to read HTML and extract data
from lxml import html
import requests
# Import collections (to obtain the OrderedDict)
import collections
#import csv
# Import date time to handle the dates in the data
from datetime import datetime
In [7]:
# Constants
URLUSSTERLING= "https://www.federalreserve.gov/releases/h10/hist/dat00_uk.htm"
URLUSEURO="https://www.federalreserve.gov/releases/h10/hist/dat00_eu.htm"
DATE="Date"
RATE="Rate"
In [8]:
# Function definitions
# Obtain exchange rate from US Federal Reserve website (via supplied URL)
# Note: the direction of the exchange differs for each currency - Euro and GBP are the same direction
def get_US_exchange_rates(aURL):
exchangerates=collections.OrderedDict()
# Get the page from the URL
# print("Get page")
page = requests.get(aURL)
# Make an HTML tree from the text
# print("Make HTML page")
tree = html.fromstring(page.content)
# The data is in a table of class="pubtables"
r=tree.xpath("//table[@class='pubtables']/tr")
# Iterate over the selected XPATH elements
# print("Iterate over xpath")
for x in r:
if x[1].text_content().strip()!="ND":
exchangerates[datetime.strptime(x[0].text_content().strip(),"%d-%b-%y")]=float(x[1].text_content().strip())
# Note: the values need to be "floated" so the scaling works
# print("Done")
return exchangerates
# Functions to obtain scaling for Y axes, rounding up to the next 0.1, down to the next 0.1
def round_up_to_tenth(value):
return float(int((value*10)+1))/10
def round_down_to_tenth(value):
return float(int((value*10)-1))/10
# Get the max of the two values rounded up to the next 0.1
def round_up_to_tenth_max_of_two(value1,value2):
result=round_up_to_tenth(value1)
roundup2=round_up_to_tenth(value2)
if result<roundup2:
result=roundup2
return result
# Get the max of the two values rounded down to the next 0.1
def round_down_to_tenth_max_of_two(value1,value2):
result=round_down_to_tenth(value1)
roundup2=round_down_to_tenth(value2)
if result>roundup2:
result=roundup2
return result
In [9]:
# Get US dollar to Sterling rate
c=get_US_exchange_rates(URLUSSTERLING)
print("US rates found")
#c
In [10]:
# Make a dataframe from the exchange rates (renaming the columns)
dfus=pandas.DataFrame([x,c[x]] for x in c)
dfus.rename(columns={0: DATE, 1: RATE}, inplace=True)
# Display the last five rows from the data frame
dfus.tail()
Out[10]:
In [11]:
# Get the US dollar to Euro exchange rates
c=get_US_exchange_rates(URLUSEURO)
print("EU rates found")
#c
In [12]:
# Make a dataframe from the exchange rates (renaming the columns)
dfeu=pandas.DataFrame([x,c[x]] for x in c)
dfeu.rename(columns={0: DATE, 1: RATE}, inplace=True)
# Display the last five rows from the data frame (just to sanity check the values)
dfeu.tail()
Out[12]:
In [13]:
# Merge the two dataframes (inner merge so there will be both exchange rates for each date)
df=merge(dfus,dfeu,on=DATE)
df.rename(columns={RATE+"_x": RATE+"_US",RATE+"_y": RATE+"_EU"}, inplace=True)
# Convert US to Euro to Euro to Sterling
df[RATE+"_EU"]=df[RATE+"_US"]/df[RATE+"_EU"]
# Only include data from the beginning of 2016
df=df[df.Date>"01-Jan-2016"]
df.tail()
Out[13]:
In [14]:
# Plot exchange rates
# Set plot size
fig = plt.figure(figsize=(18, 10))
# Set the X axis format
majorLocator = MultipleLocator(100)
majorFormatter = FormatStrFormatter('%d')
years = mdates.YearLocator() # every year
months = mdates.MonthLocator() # every month
yearsFmt = mdates.DateFormatter('%Y')
ax = fig.add_subplot(111)
ax.format_xdata = matplotlib.dates.DateFormatter('%Y-%m-%d')
ax.xaxis.set_major_locator(years)
ax.xaxis.set_major_formatter(yearsFmt)
ax.xaxis.set_minor_locator(months)
# Get maximum and minimum values for the two two plots
yminimum=round_down_to_tenth_max_of_two(min(df[RATE+"_US"]),min(df[RATE+"_EU"]))
ymaximum=round_up_to_tenth_max_of_two(max(df[RATE+"_US"]),max(df[RATE+"_EU"]))
# Set Y limits and ticks
plt.ylim(ymin=yminimum,ymax=ymaximum)
plt.yticks(np.arange(yminimum, ymaximum,0.1))
# Plot the two sets of exchange rates
ax.plot(df[DATE],df[RATE+"_US"],color='b')
ax.plot(df[DATE],df[RATE+"_EU"],color='r')
# Add the legend and titles
plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3,
ncol=2, mode="expand", borderaxespad=0.)
plt.title('Exchange Rates')
plt.xlabel('Date')
plt.ylabel('Rate', multialignment='center')
fig.autofmt_xdate()