There are number of tests that can be made of PPP. These include:
Absolute PPP: test whether prices for the same goods are equal across different exchange rates.
Relative PPP graph: test whether changes in relative prices are similar to the change in the exchange rate.
Real exchange rate stationarity: test whether the real exchange rate \((S*\frac{P^*}{P})\) is stationary.
Real exchange rate is stationary: check to see if the real exchange rate is stationary.
We are using monthly data for the India Rupiah relative to the US dollar and the CPI indices for India and the US for the period January 2008 to December 2018. The data are from the St. Louis Fed but they can also be obtained from Bloomberg. We will read the data from a csv file, rebase the data and plot.
# Read the data
da <- read.csv('../../Data/IndianUSPPP.csv')
# Make the date a date object
da$Date <- as.Date(da$Date, format = "%Y-%m-%d")
# Create more user-friendly column names
colnames(da) <- c("Date", "INDUSD", "USCPI", "ICPI")
# Take a look at the data
head(da)
## Date INDUSD USCPI ICPI
## 1 2008-01-01 39.2676 89.06 51.26
## 2 2008-02-01 39.6735 89.32 51.64
## 3 2008-03-01 40.1452 90.09 52.41
## 4 2008-04-01 39.9668 90.64 52.79
## 5 2008-05-01 42.0019 91.40 53.17
## 6 2008-06-01 42.7633 92.32 53.55
There are some issues with using Consumer Price (CPI) data as these will include services that are not tradable and therefore not likely to influence the value of the exchange rate. We might check the results with producer prices or unit labour costs. Are they the same?
# Create a vector of relative prices called Relprice in the data frame da
da$Relprice <- da$ICPI/da$USCPI
# Re-base the relative prices to the first row [1]. Call this RPreba
da$RPreba <- da$Relprice/da$Relprice[1] * da$INDUSD[1]
# Plot the exchange and colour red
plot(da$Date, da$INDUSD, col = 'red', type = 'l',
main = "India-US PPP", xlab = "Year", ylab = "Exchange rate")
# Add the RPrebal, use dotted line (lty = 2) and default colour (black)
lines(da$Date, da$RPreba, lty = 2)
# Create a legend to identify the lines
legend('topleft', inset = 0.05, legend = c("IND-USD", "Relative Prices"),
col = c('red', 'black'), lty = c(1, 2), cex = 0.7)
We have arbitrarily chosen January 2008 as the base date. However, there is no evidence that this is a period of equilibrium. I would like to check that by assessing inflation, unemployment and trade data for India and the US. The base date should be one where inflation and unemployment is about average for the two countries and where the bilateral or overall trade position seems to be stable.
Assuming that we have done that an found the beginning of 2012 to be a suitable date, we can set a base date of January 2012.
# Set the base date as January 2012
basedate <- as.Date("2012-01-01")
# Now base the rebalance on the row where the Date == basedate
da$RPrebal <- da$Relprice/da$Relprice[da$Date == basedate] *
da$INDUSD[da$Date == basedate]
# Replot the data
plot(da$Date, da$INDUSD, col = 'red', type = 'l', lty = 1,
main = "India-US PPP (base Jan 2012)", xlab = "Year",
ylab = "Exchange rate")
lines(da$Date, da$RPrebal, lty = 2)
legend('topleft', inset = 0.05, legend = c("IND-USD", "Relative Prices"),
col = c('red', 'black'), lty = c(1, 2), cex = 0.7)
This looks a lot better. We can see that there is a reasonable fit. There is a period where the Rupiah is under-valued between 2008 and 2009 and again in 2014 and late 2018. There is a period where the Rupiah is overvalue in 2011 and late 2017 to 2018.
It would be useful now to check whether export and imports or import prices confirm these indications.
It would normally be best to assess PPP between two countries with similar levels of economic development (per capita GDP) or at least during a period where there is not much change in development. Tushar Sen; The Economics of A Burger has some non-peer-reviewed research on Big Macs and productivity. You might try to reproduce that.
Stationary series are data that have stationary moments and other statistics. That means that the statistics that describe the series (like mean, standard deviation, serial correlation) are stable over time.
set.seed(124)
ry <- rnorm(100)
y <- cumsum(1 + ry)
plot(y, type = 'l', main = "Random walk")
abline(v = 50, lty = 2)
amean <- round(mean(y[1:50]),0)
bmean <- round(mean(y[51:100]),0)
text(20, 90, labels = "A", cex = 1.2)
text(80, 90, labels = "B", cex = 1.2)
text(25, 40, labels = paste("Mean part A equals ", amean))
text(75, 40, labels = paste("Mean part B equals ", bmean))
\[y_t = \rho y_{t-1} + \varepsilon\]
\(\rho\) is estimated as unit or one. If this is the case, any shock (from \(\varepsilon\)) will be permanent and y will wander in an unconstrained manner. In that case, there is no reason why the mean (or any other descriptive statistics that we calculate for y) will be stable over different samples. If \(\rho\) is estimated at one, the series is said to have a unit root and is therefore non-stationary.
The real exchange rate is
\[S \times \frac{P^*}{P}\] We can plot the real exchange rate
plot(da$Date, da$INDUSD * da$USCPI/da$ICPI,
type = 'l', main = "IND-USD Real Exchange Rate",
xlab = "Year", ylab = "Real Exchange Rate")
It seems that outside the period 2008 to 2010, there is some stability. If we restrict the data to post-2012 and re-plot, the data look stationary.
# Create a sub-set
dasub <- subset(da, da$Date >= as.Date("2012-01-01"))
# Same plot as above
plot(dasub$Date, dasub$INDUSD * dasub$USCPI/dasub$ICPI,
type = 'l', main = "IND-USD Real Exchange Rate (2012-2018)",
xlab = "Year", ylab = "Real Exchange Rate")
# Draw line around the mean of the real exchange rate
# Using abline that will draw lines on a graph
REmean <- mean(dasub$INDUSD * dasub$USCPI / dasub$ICPI)
abline(h = REmean, col = 'red', lty = 2)
legend('top', inset = 0.05, legend = c("Real Rate", "Mean"),
col = c('black', 'red'), lty = c(1,2), cex = 0.7)
We can use the urca package to find unit root
tests. The documentation will discuss a number of different
options. The Augmented Dicky-Fuller Test (ADF) is the
most popular. This is based on testing the null that \(\rho\) is equal to one in the following
equation:
\[y_t = \rho y_{t-1} + \varepsilon_t\] The usual test is then
\[\Delta y_t = (\rho - 1)y_{t-1} + \varepsilon_t\] or
\[\Delta y_y = \delta y_{t-1} + \varepsilon_t\]
where \(\delta\) is equal to \(\rho - 1\) so that if \(\delta = 0, \rho = 1\)
In practice, it is usual to add lags of the dependent variable \((y)\) to remove serial correlation and to test three forms:
\[\Delta y_t = \delta y_{t-1} + \varepsilon_t\]
\[\Delta y_t = \alpha_0 + \delta y_{t-1} + \varepsilon_t\]
\[\Delta y_t = \alpha_0 + \alpha_1 t + \delta y_{t-1} + \varepsilon_t\] The critical values are not standard and change for each version of the test. From looking at the residuals, it appears that we are dealing with no drift and no time trend.
require(urca)
RealRate <- dasub$INDUSD * dasub$USCPI / dasub$ICPI
summary(ur.df(RealRate, type = 'drift'))
##
## ###############################################
## # Augmented Dickey-Fuller Test Unit Root Test #
## ###############################################
##
## Test regression drift
##
##
## Call:
## lm(formula = z.diff ~ z.lag.1 + 1 + z.diff.lag)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.24907 -0.82304 -0.00146 0.71374 3.02270
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 15.4631 4.2972 3.598 0.000557 ***
## z.lag.1 -0.2403 0.0669 -3.591 0.000570 ***
## z.diff.lag 0.2340 0.1071 2.185 0.031841 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 1.084 on 79 degrees of freedom
## Multiple R-squared: 0.1513, Adjusted R-squared: 0.1298
## F-statistic: 7.041 on 2 and 79 DF, p-value: 0.001534
##
##
## Value of test-statistic is: -3.5913 6.4947
##
## Critical values for test statistics:
## 1pct 5pct 10pct
## tau2 -3.51 -2.89 -2.58
## phi1 6.70 4.71 3.86
There are two tests. One of \(\tau\) and one of \(\phi\). In each case we can reject the unit root at the 1 percent level. The first test \(\tau\) is the test of the unit root. We reject the null. It seems that the nominal exchange rate is stationary when we have a drift or intercept term. The second test \(\phi\) is a test of the join hypothesis that the coefficient on the drift term or intercept and the coefficient on the lagged level of the dependent variable.
The monetary model is an extension of PPP. It suggests that excess money above that needed for transactions and savings will push up prices and that this will cause a depreciation of the exchange rate.
Now, given that money demand at home is related to the transaction demand (represented by the expenditure measure of GDP) less the opportunity cost of holding money (measured as the interest rate),
\[m-p=\alpha y + \beta i\] and abroad \[m^*-p^*=\alpha y^* + \beta i^{*}\]
Nominal exchange rate is related to relative money growth
\[s=(m-m^*)-\alpha (y-y^*) - \beta(i-i^*)\]
It is possible to test this model by taking an appropriate measure of money supply, GDP and interest rates. The difficulty would be in measuring how swiftly money demand and prices respond to changes in the money stock.