Ols regression analysis Mortgage rates and House prices

Collins A. Hackman

March 29, 2022

Data Source: FRED

ANALYSIS

Since 30 year mortgage rates index is stationary according to the aggregate dickey fueller testing, I ran an Ols regression on it as the endogenous Y variable on the housing price index exogenous variable which is not stationary using the ADF test

Looking at the coefficients result, when house prices go up by 1, mortgage rates would go down by -0.02 (ps no log-log/log-linear/linear-log use here).

However, there are a few exceptions shown in the 4 plotted graphs below, from 2007 to 2012, they both went down.

Data Manipulation

#making excel data time series and a dataframe
data1 <- read_excel("C:/Users/kofij/Documents/morthouse.xlsx")
data1d <- as.data.frame(data1)
head(data1d, 3)
        Date USSTHPI MORTGAGE30US
1 1975-01-01 61.0900     9.047115
2 1976-01-01 65.5225     8.865849
3 1977-01-01 73.4300     8.845192
data1nodate <- as.data.frame(cbind(data1d[, "MORTGAGE30US"], ~data1d[, "USSTHPI"]))
data2 <- ts(data1d)
head(data2, 3)
          Date USSTHPI MORTGAGE30US
[1,] 157766400 61.0900     9.047115
[2,] 189302400 65.5225     8.865849
[3,] 220924800 73.4300     8.845192

Code Error

**k-nearest neighbor is not fitting due to installation problems with tidymodels**

#lm model code below is not working

lm_model <- linear_reg() %>% 
  set_engine('kknn') %>% 
  set_mode('regression') %>%
  fit(data1d[, "MORTGAGE30US"] ~ data1d[, "USSTHPI"], data = data1d) 

Regression Fit

#plotting the dataframe with regression fit
g <- plot_ly(data1d, x = ~data1d[, "MORTGAGE30US"], y = ~data1d[, "USSTHPI"], 
             type = 'scatter', alpha = 0.65, mode = 'markers', 
             name = 'Group 4')
g <- g %>% add_trace(data = data1nodate, x=~data1d[, "MORTGAGE30US"], 
                     y = ~data1d[, "USSTHPI"], name = 'Regression Fit', 
                     mode = 'lines', alpha = 1)
g

ADF test for stationarity

# ADF testing of two indices

# Mortgage Series
s1 <- ur.df(data1d[, "MORTGAGE30US"], type = "trend", selectlags = "BIC")
summary(s1)

############################################### 
# Augmented Dickey-Fuller Test Unit Root Test # 
############################################### 

Test regression trend 


Call:
lm(formula = z.diff ~ z.lag.1 + 1 + tt + z.diff.lag)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.27260 -0.56022 -0.04496  0.43869  2.39109 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  4.25201    1.08627   3.914 0.000335 ***
z.lag.1     -0.31256    0.07933  -3.940 0.000310 ***
tt          -0.07806    0.02026  -3.853 0.000402 ***
z.diff.lag   0.40178    0.12940   3.105 0.003444 ** 
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 0.8318 on 41 degrees of freedom
Multiple R-squared:  0.3543,    Adjusted R-squared:  0.3071 
F-statistic:   7.5 on 3 and 41 DF,  p-value: 0.0004106


Value of test-statistic is: -3.9402 5.5686 8.0957 

Critical values for test statistics: 
      1pct  5pct 10pct
tau3 -4.15 -3.50 -3.18
phi2  7.02  5.13  4.31
phi3  9.31  6.73  5.61
# House series
s2 <- ur.df(data1d[, "USSTHPI"], type = "trend", selectlags = "BIC")
summary(s2)

############################################### 
# Augmented Dickey-Fuller Test Unit Root Test # 
############################################### 

Test regression trend 


Call:
lm(formula = z.diff ~ z.lag.1 + 1 + tt + z.diff.lag)

Residuals:
    Min      1Q  Median      3Q     Max 
-19.247  -3.193  -0.851   1.725  40.218 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  2.04945    3.22624   0.635   0.5288    
z.lag.1     -0.10714    0.05134  -2.087   0.0431 *  
tt           1.03771    0.43313   2.396   0.0212 *  
z.diff.lag   0.98022    0.12145   8.071  5.3e-10 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 8.371 on 41 degrees of freedom
Multiple R-squared:  0.6472,    Adjusted R-squared:  0.6214 
F-statistic: 25.07 on 3 and 41 DF,  p-value: 2.242e-09


Value of test-statistic is: -2.0871 2.7127 3.4654 

Critical values for test statistics: 
      1pct  5pct 10pct
tau3 -4.15 -3.50 -3.18
phi2  7.02  5.13  4.31
phi3  9.31  6.73  5.61

Detrending {USSTHPI} House price index

\(Log\) \(difference\) \(of\) \(Housing\) \(price\) \(and\) \(Rates\) \(indices\)

loghouse <- 100 * diff(log(data1d[, "USSTHPI"]))
loghouse1 <- cbind(data1d[, "Date"], loghouse)
loghousedf <- as.data.frame(loghouse1)

Detrending {MORTGAGE30US} 30 year fixed mortgaeg rate index

\(Log\) \(difference\) \(of\) \(30\) \(year\) \(mortgage\) \(rates\)

logmort <- 100 * diff(log(data1d[, "MORTGAGE30US"]))
logmort <- cbind(data1d[, "Date"], logmort)
logmortdf <- as.data.frame(logmort)

Plots

# plots
p1 <- data1d %>% plot_ly(x=~data1d[, "Date"], y=~data1d[, "MORTGAGE30US"], 
                         type="scatter", mode="line", fill="tonexty", name="1 RATES")
p2 <- data1d %>% plot_ly(x=~data1d[, "Date"], y=~data1d[, "USSTHPI"], 
                         type="scatter", mode="line", fill="tozeroy", name="2 HOUSE")
p3 <- loghousedf %>% plot_ly(x=~data1d[, "Date"], y=~loghouse, 
                         type="scatter", mode="line", fill="tozeroy",name="3 LOG HOUSE")
p4 <- logmortdf %>% plot_ly(x=~data1d[, "Date"], y=~logmort, 
                             type="scatter", mode="line", fill="tonexty",name="4 LOG RATES")
subplot(p1,p2,p3,p4, nrows=4)

OLS Regression on the indices

# Runnning OLS on the two
reg <- lm(data1d[, "MORTGAGE30US"]~data1d[, "USSTHPI"], data1d)
summary(reg)

Call:
lm(formula = data1d[, "MORTGAGE30US"] ~ data1d[, "USSTHPI"], 
    data = data1d)

Residuals:
    Min      1Q  Median      3Q     Max 
-3.0420 -1.0939 -0.2096  0.7491  5.7194 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)    
(Intercept)         13.456190   0.622925   21.60  < 2e-16 ***
data1d[, "USSTHPI"] -0.023631   0.002324  -10.17 3.06e-13 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 1.898 on 45 degrees of freedom
Multiple R-squared:  0.6968,    Adjusted R-squared:  0.6901 
F-statistic: 103.4 on 1 and 45 DF,  p-value: 3.06e-13
# Residual plosts
plot(reg)