# 1.
cd /course/users/yran945/lab-2
curl https://api.frankfurter.app/2023-01-01..2023-12-31?to=NZD > nzd-2023.json
# 2.
curl https://api.frankfurter.app/2020-01-01..2023-12-31?to=USD,GBP,AUD,NZD > long.json
## % Total % Received % Xferd Average Speed Time Time Time Current
## Dload Upload Total Spent Left Speed
##
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 7207 100 7207 0 0 60563 0 --:--:-- --:--:-- --:--:-- 60563
## % Total % Received % Xferd Average Speed Time Time Time Current
## Dload Upload Total Spent Left Speed
##
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 14215 100 14215 0 0 99405 0 --:--:-- --:--:-- --:--:-- 99405
# 3.
library("jsonlite")
nzd <- unlist(fromJSON("nzd-2023.json"))
date <- names(nzd)[-(1:4)]
date <- as.Date(substring(date,7,16))
nzd_num <- as.numeric(unname(nzd)[-(1:4)])
nzd <- data.frame(date,nzd = nzd_num)
str(nzd)
## 'data.frame': 255 obs. of 2 variables:
## $ date: Date, format: "2023-01-02" "2023-01-03" ...
## $ nzd : num 1.69 1.69 1.68 1.68 1.69 ...
# 4.
rates.json <- fromJSON("long.json")$rates
rate <- as.vector(unlist(rates.json))
date <- names(rates.json)
country <- names(rates.json[[1]])
rates.m <- matrix(rate, ncol = 4, byrow = TRUE,
dimnames = list(date, country))
str(rates.m)
## num [1:209, 1:4] 1.6 1.62 1.61 1.62 1.64 ...
## - attr(*, "dimnames")=List of 2
## ..$ : chr [1:209] "2019-12-30" "2020-01-06" "2020-01-13" "2020-01-20" ...
## ..$ : chr [1:4] "AUD" "GBP" "NZD" "USD"
# 5.
summary(nzd$nzd)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1.668 1.732 1.765 1.762 1.798 1.841
plot(nzd, cex= 0.4, type="l", main = "EUR to NZD Exchange Rates in 2023")

## The exchange rate of EUR to NZD fluctuated between 1.668 and 1.841. It exhibited an upward trend until September, followed by a downward trend with sharp declines in May, October, and December. Overall, the euro appreciated against the New Zealand dollar in 2023. The mean exchange rate was 1.762, and the median was 1.765. The proximity of the mean to the median indicates a relatively symmetrical distribution of exchange rates.
# 6.
summary(rates.m)
## AUD GBP NZD USD
## Min. :1.439 Min. :0.8306 Min. :1.578 Min. :0.9662
## 1st Qu.:1.554 1st Qu.:0.8533 1st Qu.:1.670 1st Qu.:1.0722
## Median :1.597 Median :0.8637 Median :1.697 Median :1.1022
## Mean :1.594 Mean :0.8680 Mean :1.712 Mean :1.1150
## 3rd Qu.:1.638 3rd Qu.:0.8820 3rd Qu.:1.764 3rd Qu.:1.1756
## Max. :1.838 Max. :0.9171 Max. :1.863 Max. :1.2286
### On average, NZD is the highest,GBP is the lowest.
# Compute the differences
apply(rates.m, 2, max)-apply(rates.m, 2, min)
## AUD GBP NZD USD
## 0.39940 0.08648 0.28540 0.26242
### During this period, AUD has the greatest fluctuation.
head(nzd$date)
## [1] "2023-01-02" "2023-01-03" "2023-01-04" "2023-01-05" "2023-01-06"
## [6] "2023-01-09"
head(rownames(rates.m))
## [1] "2019-12-30" "2020-01-06" "2020-01-13" "2020-01-20" "2020-01-27"
## [6] "2020-02-03"
### The date patterns are not the same. The nzd data frame contains data for each day, while rates.m contains data for each week. Because Frankfurter returns all data points for up to 90 days. Above that, it starts sampling by week or month based on the breadth of the date range.
# 7.
matplot(as.Date(rownames(rates.m)), rates.m, type = "l", lty = 1,
xlab = "Date", ylab = "Exchange rate", main = "Exchange rates vs EUR")
legend("right", legend = colnames(rates.m), col = 1:4, lty = 1)

# 8.
rates.m_subset <- data.frame(date, NZD.m = unname(rates.m[,"NZD"]))
merged_subset <- merge(rates.m_subset, nzd, by = "date")
merged_subset$equal = ifelse(merged_subset$NZD.m == merged_subset$nzd, 1, 0)
cat("The number of equal entry is", length(which(merged_subset$equal==1)))
## The number of equal entry is 0
### So the NZD exchange rates in nzd is not a subset of rates.m. The exchange rates in the rates.m data frame are not the actual daily rates; they are adjusted values.
# 9.
rates <- as.data.frame(rates.m)
pairs(rates, pch=19, col=4)

## NZD and AUD have a strong positive linear relationship, so AUD behaves the most similarly to NZD. Due to their proximity and close economic ties, the exchange rates of the two countries show similar variation.
# 10.
AUD_model <- lm(rates.m[,"NZD"] ~ rates.m[,"AUD"])
GBP_model <- lm(rates.m[,"NZD"] ~ rates.m[,"GBP"])
USD_model <- lm(rates.m[,"NZD"] ~ rates.m[,"USD"])
AUD_model$coefficients
## (Intercept) rates.m[, "AUD"]
## 0.4497751 0.7919542
GBP_model$coefficients
## (Intercept) rates.m[, "GBP"]
## 0.3433418 1.5770389
USD_model$coefficients
## (Intercept) rates.m[, "USD"]
## 1.722660976 -0.009441864
### Interpretation: when the USD exchange rate is 0, the NZD exchange rate is 1.722661. For each additional USD rate increase, NZD rate decreases by 0.009, indicating a weak relationship between them.
cat("RMSE of AUD model is", sqrt(mean(AUD_model$residuals^2)))
## RMSE of AUD model is 0.02897987
cat("\nRMSE of GBP model is", mean(GBP_model$residuals^2))
##
## RMSE of GBP model is 0.002569346
cat("\nRMSE of USD model is", mean(USD_model$residuals^2))
##
## RMSE of USD model is 0.003691712
# RMSE of AUD is the smallest,so AUD_model is the best. It matches the expectation from question 9.
# 12. A summary of findings
### First, we explored the relationship between NZD rates and EUR rates in 2023. The exchange rate fluctuated throughout the year, but overall, it increased. We found that the NZD exchange rate collected over one year differs from the values collected over four years for the same days due to different statistical methods used.
### Next, we observed the changes in AUD, GBP, NZD, and USD from 2020 to 2023 and investigated which currency behaves most similarly to NZD. By examining the plots and building three linear models with RMSE calculations, we obtained consistent results—AUD behaves the most similarly to NZD. Due to their proximity and close economic ties, the exchange rates of the two countries exhibit similar changes.