# Start by loading the libaries we'll need throughout
import pandas as pd
import plotly.express as px
All of this charts in this notebook are from this BIS dataset, which I have manually cleaned. We start by showing what the dataframe looks like, so that we know what we're working with.
# Data is from https://www.bis.org/statistics/xrusd.htm?m=2675
# These are the ~50 currencies' monthly average exchange rates for which the longest series to today were available
# So far, I have manually pre-cleaned this dataset, mostly by ":" separating the column headers
df=pd.read_csv('BIS_Monthly50_2022-03.csv')
#df.set_index('Month',inplace=True)
df
Month | GBP:Pound (sterling):United Kingdom | ZAR:South African Rand:South Africa | EUR:Euro:Portugal | ARS:Argentine peso:Argentina | PHP:Philippine peso:Philippines | HUF:Forint:Hungary | USD:US dollar:United States | TRY:Turkish lira:Turkey | CAD:Canadian dollar:Canada | ... | EUR:Euro:Luxembourg | EUR:Euro:Malta | MUR:Mauritius rupee:Mauritius | MYR:Malaysian ringgit:Malaysia | NZD:New Zealand dollar:New Zealand | OMR:Omani rial:Oman | PLN:Zloty:Poland | RON:Romanian leu:Romania | SGD:Singapore dollar:Singapore | THB:Baht:Thailand | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1791-01 | 0.220151 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
1 | 1791-02 | 0.220151 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
2 | 1791-03 | 0.222331 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
3 | 1791-04 | 0.220151 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
4 | 1791-05 | 0.225117 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | ... | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
2770 | 2021-11 | 0.742882 | 15.515413 | 0.876236 | 100.310071 | 50.353344 | 319.425962 | 1.0 | 10.731658 | 1.256419 | ... | 0.876236 | 0.876236 | 43.188388 | 4.178865 | 1.424877 | 0.3845 | 4.071543 | 4.336810 | 1.356941 | 33.093675 |
2771 | 2021-12 | 0.750860 | 15.864837 | 0.884663 | 101.888500 | 50.351875 | 325.112165 | 1.0 | 13.628418 | 1.279445 | ... | 0.884663 | 0.884663 | 43.446829 | 4.210906 | 1.472845 | 0.3845 | 4.081543 | 4.378376 | 1.362686 | 33.555844 |
2772 | 2022-01 | 0.738057 | 15.492416 | 0.883871 | 103.984600 | 51.262052 | 317.031148 | 1.0 | 13.568861 | 1.262351 | ... | 0.883871 | 0.883871 | 43.613717 | 4.189757 | 1.483948 | 0.3845 | 4.023640 | 4.371100 | 1.350985 | 33.238098 |
2773 | 2022-02 | 0.738761 | 15.223552 | 0.881733 | 106.307110 | 51.281629 | 314.778913 | 1.0 | 13.658243 | 1.271602 | ... | 0.881733 | 0.881733 | 43.772324 | 4.187372 | 1.497302 | 0.3845 | 4.011027 | 4.360864 | 1.346710 | 32.634954 |
2774 | 2022-03 | 0.759054 | 14.987056 | 0.907563 | 109.458500 | 52.106735 | 341.840979 | 1.0 | 14.632688 | 1.265996 | ... | 0.907563 | 0.907563 | 44.122700 | 4.199719 | 1.456521 | 0.3845 | 4.313145 | 4.490837 | 1.358747 | 33.259572 |
2775 rows × 50 columns
We start with the British Pound simply because it has the longest data series from BIS on its exchange rate versus the US dollar. It is remarkable that from the end of the War of 1812 until the start of World War II in 1939, the GBP/USD exchange rate spent most of its time in a tight range of around 4.85 US dollars to the Pound with three notable exceptions:
The pound then spent the 1940s at a very stable exchange rate of around 4 dollars, in the middle of which was the 1944 Bretton Woods Conference (https://2001-2009.state.gov/r/pa/ho/time/wwii/98681.htm), where several countries agreed to try and maintain fixed exchange rates to the US dollar, which in turn was pegged to 1/35 ounce of gold until 1971.
# Convert the BIS USD/GBP series into GBP/USD, then plot
df['GBP/USD']=1.0/df['GBP:Pound (sterling):United Kingdom']
fig = px.line(df, x="Month", y='GBP/USD', title='British Pound / US Dollar Exchange Rate, 1791-2022')
fig.show()
Oddly enough, it was only a few years after the start of Bretton Woods that the pound saw its next major devaluation from around 4 dollars to around 2.8 dollars in late 1949. I will use this point to mark 1950 as the start of the "modern era of the British Pound", which we zoom in on in this next chart. We see that the GBP/USD rate of 2.8 was maintained from the end of 1949 until the Harold Wilson devaluation to 2.4 in 1967 (https://www.nationalarchives.gov.uk/cabinet-office-100/the-1967-devaluation-of-the-pound/), where the exchange rate largely remained until the US broke the gold standard on August 15th, 1971 (https://history.state.gov/milestones/1969-1976/nixon-shock). That period between the 1967 and the day the British Pound decimalized on February 15th 1971 (https://www.bullionbypost.co.uk/index/collectible-coins/decimalisation/) is remembered by some as the rare time that one British penny (which was then 1/240th of a pound) happened to be worth one US penny (which as been worth 1/100th of a dollar since 1787: https://coins.nd.edu/ColCoin/ColCoinIntros/Fugio.intro.html).
While the pound initially rose to 2.6 dollars shortly after the "Nixon Shock", the GBP/USD trend from 1971-2021 could be described as a clear but volatile decline.
fig = px.line(df[df['Month']>='1950-01'], x="Month", y='GBP/USD', title='British Pound / US Dollar Exchange Rate, 1950-2022')
fig.show()
We charted GBP/USD first because it had by far the longest historic data series, but below are almost 50 other currencies for which we also have USD exchange rate data from BIS for at least the past 60 years. Looking at this list, here is how I would plan to group them:
The below count shows the whole list of currencies in the cleaned data set, along with the number of months of historic exchange rates we have on each.
df.count()
Month 2775 GBP:Pound (sterling):United Kingdom 2775 ZAR:South African Rand:South Africa 1467 EUR:Euro:Portugal 1362 ARS:Argentine peso:Argentina 987 PHP:Philippine peso:Philippines 927 HUF:Forint:Hungary 879 USD:US dollar:United States 879 TRY:Turkish lira:Turkey 867 CAD:Canadian dollar:Canada 858 BRL:Brazilian real:Brazil 831 EUR:Euro:Belgium 823 CHF:Swiss franc:Switzerland 823 EUR:Euro:Germany 823 DKK:Danish krone:Denmark 823 EUR:Euro:France 823 EUR:Euro:Netherlands 823 SEK:Swedish krona:Sweden 823 NOK:Norwegian krone:Norway 820 MXN:Mexican peso:Mexico 816 EUR:Euro:Italy 800 EUR:Euro:Austria 783 AUD:Australian dollar:Australia 783 BND:Brunei dollar:Brunei 783 CLP:Chilean peso:Chile 783 CNY:Renminbi:China 783 COP:Colombian peso:Colombia 783 EUR:Euro:Cyprus 783 DZD:Algerian dinar:Algeria 783 EUR:Euro:Spain 783 EUR:Euro:Finland 783 EUR:Euro:Greece 783 HKD:Hong Kong dollar:Hong Kong SAR 783 EUR:Euro:Ireland 783 ILS:New shekel:Israel 783 INR:Indian rupee:India 783 ISK:Icelandic krona:Iceland 783 JPY:Yen:Japan 783 KRW:Won:Korea 783 LKR:Sri Lanka rupee:Sri Lanka 783 EUR:Euro:Luxembourg 783 EUR:Euro:Malta 783 MUR:Mauritius rupee:Mauritius 783 MYR:Malaysian ringgit:Malaysia 783 NZD:New Zealand dollar:New Zealand 783 OMR:Omani rial:Oman 783 PLN:Zloty:Poland 783 RON:Romanian leu:Romania 783 SGD:Singapore dollar:Singapore 783 THB:Baht:Thailand 783 GBP/USD 2775 dtype: int64
We next look at the South African Rand because it has the second longest data series, and plot it alongside the British pound, against which it seems to have been pegged until the early 1980s.
df['ZAR/USD']=1.0/df['ZAR:South African Rand:South Africa']
fig = px.line(
df[df['ZAR:South African Rand:South Africa'].notna()],
x="Month",
y=['GBP/USD','ZAR/USD'],
title='British Pound and South African Rand vs the US Dollar, 1900-2022')
fig.update_layout(legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1,
title=""
))
fig.show()
Australia and Canada have historic and ongoing links with the UK, but unlike the British Pound, these two currencies tend to more closely reflect the natural resource intensive nature of these two economies, which might be one explanation for why these two currencies have been more stable against the US dollar than the pound has over the past 50 years.
df['CAD/USD']=1.0/df['CAD:Canadian dollar:Canada']
df['AUD/USD']=1.0/df['AUD:Australian dollar:Australia']
# y=['GBP:Pound (sterling):United Kingdom','CAD:Canadian dollar:Canada','AUD:Australian dollar:Australia'],
fig = px.line(
df[df['CAD:Canadian dollar:Canada'].notna()],
x="Month",
y=['GBP/USD','CAD/USD','AUD/USD'],
title='The Canadian and Australian Dollars have been more stable than the Pound, 1950-2022')
fig.update_layout(legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1,
title=""
))
fig.show()
These are just five of the dozen national currencies that became the Euro in 1999-2001, so have ceased to be individual currencies since, but looking at how these different currencies appreciated or depreciated to the levels at which they were pegged to the Euro provides important insights on the background of these many different economies that have joined the common currency.
The Portuguese Escudo happens to have a longer data history, and one with a far more extreme devaluation chart against the the dollar, so would be better charted separately.
df['Portuguese Escudo']=1.0/df['EUR:Euro:Portugal'] # longer history we could chart separately, but won't for now
df['German Mark']=1.0/df['EUR:Euro:Germany']
df['French Franc']=1.0/df['EUR:Euro:France']
df['Italian Lira']=1.0/df['EUR:Euro:Italy']
df['Dutch Guilder']=1.0/df['EUR:Euro:Netherlands']
fig = px.line(
df[df['EUR:Euro:Germany'].notna()],
x="Month",
y=['German Mark','French Franc','Italian Lira','Dutch Guilder'],
title='Four Currencies Before They Became The Euro, 1953-2022')
fig.update_layout(legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1,
title=""
))
fig.show()
Three European currencies which did not join the Euro have followed two divergent paths:
The high correlation between Sweden and Norway is notable, as Sweden is in the EU and Norway is not, and the economy of the latter is more related to crude oil than the former.
df['Swiss franc']=1.0/df['CHF:Swiss franc:Switzerland']
df['Swedish krona']=1.0/df['SEK:Swedish krona:Sweden']
df['Norwegian krone']=1.0/df['NOK:Norwegian krone:Norway']
fig = px.line(
df[df['Norwegian krone'].notna()],
x="Month",
y=['Swiss franc','Swedish krona','Norwegian krone'],
title='Three Non-Euro European Currencies, 1953-2022')
fig.update_layout(legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1,
title=""
))
fig.show()
In the far east, two currencies stand out as long-term appreciators since 1971: the Japanese yen and Singapore dollar.
df['Japanese Yen (x100)']=100.0/df['JPY:Yen:Japan']
df['Singapore dollar']=1.0/df['SGD:Singapore dollar:Singapore']
fig = px.line(
df[df['Japanese Yen (x100)'].notna()],
x="Month",
y=['Japanese Yen (x100)','Singapore dollar'],
title='Japanese Yen and Singapore Dollar, 1953-2022')
fig.update_layout(legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1,
title=""
))
fig.show()
Five other Asian currencies, those of Philippines, Thailand, Korea, China, and India, mostly seem to show similar patterns of long-term depreciation that began in the 1960s, even before the collapse of Bretton-Woods in 1971. China was a relative exception in this group, with its currency strengthening in the 1970s, and even though the Renminbi was unaffected by the Asian Financial Crisis in 1997, it seems to have led the way for relative stability of the Korean Won, Thai Baht, and Philippine Peso since then. Since 1997, the Indian rupee seems to be the only one of these on a relatively consistent long-term "depreciation" trajectory, as evidenced by its relatively high local interest rates, while the other four in this group seem to be trading more in a "side ways range" not unlike the Australian or Canadian dollars.
#PHP:Philippine peso:Philippines 927
#CNY:Renminbi:China 783
#KRW:Won:Korea 783
#THB:Baht:Thailand 783
#INR:Indian rupee:India 783
df['Philippine peso']=1.0/df['PHP:Philippine peso:Philippines']
df['Chinese yuan (Renminbi)']=1.0/df['CNY:Renminbi:China']
df['Korean won (x10)']=10.0/df['KRW:Won:Korea']
df['Thai baht']=1.0/df['THB:Baht:Thailand']
df['Indian rupee']=1.0/df['INR:Indian rupee:India']
fig = px.line(
df[df['Philippine peso'].notna()],
x="Month",
y=['Philippine peso','Chinese yuan (Renminbi)','Korean won (x10)','Thai baht','Indian rupee'],
log_y=True,
title='Five Asian Currencies, log scale, 1957-2022')
fig.update_layout(legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1,
title=""
))
fig.show()
Last but not least is this chart of five Latin American currencies, on a log scale showing how extreme the devaluation of these currencies has been to today's value of their current denominations.
#ARS:Argentine peso:Argentina 987
#BRL:Brazilian real:Brazil 831
#MXN:Mexican peso:Mexico 816
#CLP:Chilean peso:Chile 783
#COP:Colombian peso:Colombia 783
df['Argentine peso']=1.0/df['ARS:Argentine peso:Argentina']
df['Brazilian real']=1.0/df['BRL:Brazilian real:Brazil']
df['Mexican peso']=1.0/df['MXN:Mexican peso:Mexico']
df['Chilean peso']=1.0/df['CLP:Chilean peso:Chile']
df['Colombian peso']=1.0/df['COP:Colombian peso:Colombia']
fig = px.line(
df[df['Argentine peso'].notna()],
x="Month",
y=['Argentine peso','Brazilian real','Mexican peso','Chilean peso','Colombian peso',],
log_y=True,
title='Latin American currencies, value of 2022 denominations, log scale, 1957-2022')
fig.update_layout(legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1,
title=""
))
fig.show()