24 June 2016

In preparation for moving to Australia last year, I started monitoring the exchange rate between the USD and AUD, to get a sense of good timing to shift funds. The web site Open Exchange Rates provides an API to extract cross rates data. Carson Sievert provides some code to pull data using R here. This post is about using this data to examine the effect of the UK vote to exit the European Union.

Extract data

The last three months (roughly) of exchange rates are collected.

dat_all <- getRates(start = Sys.Date()-90, end = Sys.Date())

British pound

Using ggplot2 take a quick look at the British pound behaviour.

dat_all_inv <- dat_all %>% mutate_each(funs(inv = 1 / .), -date)

ggplot(data=dat_all_inv, aes(x=date, y=GBP)) + geom_line() +
  xlab("") +
  scale_x_date(date_breaks = "1 week", date_labels= "%d-%b",
               limits=c(as.Date("2016-06-24")-13*7, as.Date("2016-06-24")+7))

This is cross rate against the USD, so the values tell you how many GBP you need to buy 1 USD. When the results were announced the GBP dropped dramatically: the result had a big negative effect on the pound.

A few other currencies

Plotting a small selestion of other currencies, we can see that the EUR also took a hit. The AUD had a small negative reaction, but the JPY had a strong positive reaction. Note that to compare the currencies we need to get them on the same scale, so all currencies are standardised on themselves before plotting.

currency.cv <- dat_all_inv %>% summarise_each(funs(cv = sd(.)/mean(.)*100), -date)
dat_all_noUS <- dat_all_inv %>% select(-BBD, -BMD, -BSD, -CUC, -PAB, -USD)

dat_all_std <- dat_all_noUS %>% mutate_each(funs(scale), -date)
dat_all_std_m <- gather(dat_all_std, currency, std.rate, -date)

ggplot(data=dat_all_std_m, aes(x=date, y=std.rate, group=currency)) +
  geom_line(alpha=0.1) +
  xlab("") +
  scale_x_date(date_breaks = "1 week", date_labels= "%d-%b",
               limits=c(as.Date("2016-06-24")-4*7, as.Date("2016-06-24")+3)) +
  geom_line(data=filter(dat_all_std_m, currency %in% c("GBP", "EUR", "JPY", "AUD")), aes(colour=currency), alpha=0.5, size=2)

“sympathetic”, “indifferent” or “antipathic” currencies

Compute the difference between rates

drop <- names(currency.sd)[currency.cv < 0.2516]
drop.integer <- match(drop, colnames(dat_all_inv))
dat_all_nosmvar <- dat_all_inv %>% select(-drop.integer)
dat_all_nosmvar_std <- dat_all_nosmvar %>% mutate_each(funs((. - mean(.))/sd(.)), -date)
dif <- dat_all_nosmvar_std[dat_all_nosmvar_std$date==as.Date("2016-06-23"),] - dat_all_nosmvar_std[dat_all_nosmvar_std$date==as.Date("2016-06-24"),]
firstdifs <- dat_all_nosmvar_std[1:89,-129] - dat_all_nosmvar_std[2:90,-129]
dif.df <- data.frame(dif=dif, meandif=apply(firstdifs, 2, mean, na.rm=T))
dif.df$currency <- rownames(dif.df)
ggplot(dif.df, aes(x=dif, y=meandif, label=currency)) + geom_point() +
  theme(aspect.ratio=1) +
  geom_point(data=filter(dif.df, currency %in% c("GBP", "EUR", "JPY", "AUD")), aes(colour=currency), size=3, alpha=0.8)

(The code ggplotly() allows you to interact with the plot.)

To get a better sense of the reaction, all the series are centered at 0, for BrExit vote day.

keep <- dif.df %>% filter(abs(dif) > 1)
value.6.23 <- dat_all_nosmvar_std %>%
  filter(date == as.Date("2016-06-23")) %>%
value.6.23 <- as.numeric(value.6.23)
dat_sub <- data.frame(as.matrix(dat_all_nosmvar_std[,-129]) - matrix(rep(value.6.23, 93), byrow=T, nrow=93)) # Center at brexit
dat_sub$date <- dat_all_nosmvar_std$date
dat_sub_m <- dat_sub %>%
  gather(currency, ctr.rate, -date) %>%
  filter(currency %in% keep$currency)
ggplot(data=dat_sub_m, aes(x=date, y=ctr.rate, group=currency, label=currency)) +
  geom_line(alpha=0.2) +
  xlab("") +
  scale_x_date(date_breaks = "1 day", date_labels= "%d-%b",
               limits=c(as.Date("2016-06-23")-3, as.Date("2016-06-23")+2)) +
  geom_line(data=filter(dat_sub_m, currency %in% c("GBP", "XDR", "KMF", "EUR", "STD", "XAU")), aes(colour=currency), alpha=0.5, size=2)

Most of the world was shocked

dif.df <- dif.df %>% mutate(react=round(dif, 0))
dif.df$react[dif.df$react >= 2] <- 2
dif.df$react[dif.df$react <= -2] <- -2
dif.df %>% arrange(react) %>% select(currency, react)

Sympathetic currencies are:


(including combo? currencies like “ALL”, “XDR” and “KMF”.)

Antipathic currencies are:


It should be noted that “XAU” is the gold rate. Hmm. But why would “Sao Tome and Principe”=”STD”, who’s currency is supposed to be pegged to the EUR, react antipathically?

Indifferent currencies are:


And made into a map looks like this:

countries <- read_csv("http://dicook.github.io/Monash-R/data/countries.csv")
countries <- rbind(countries, c("Sao Tome and Principe", "STD"))
rates.countries <- merge(countries, dif.df)

world <- map_data("world")
world$region[world$region=="UK"] <- "United Kingdom"
world$region[world$region=="Russia"] <- "USSR"
rates.map <- merge(rates.countries, world, by.x="name", by.y="region")
rates.map <- rates.map[order(rates.map$order),]
ggplot(data=rates.map) + geom_polygon(aes(x=long, y=lat, group=group, order=order, fill=factor(react))) + scale_fill_brewer(palette="PRGn") +

Strong negative reactions can be seen in Europe, with moderate reactions in much of the rest of the world. Moderate positive reactions can be seen in disparate countries, and a shrug can be seen in a few other places (some controlled not to react, like CNY).

blog comments powered by Disqus