I am trying to investigate the stability of spread between two short-term interest rates by the example of 1M and 12M Euribor.

I don't think only looking at correlations over time is statisically enough to infer the stability of the spread.

My first thought would be to use a regression framework in which I regress 12M euribor (Y) on 1M (X) and suppress the intercept, because the difference between Y and X will be then only the residual and thus the spread.

Then, it could be tested whether the regression coefficient (Beta) = 1 and whether has remained 1 over time (implying that 12M - 1M is the term spread), and tested whether the residual (term spread) is stationary implying constant spread over time.

I was thinking to use the Engle Granger cointegration test. However, I don't know if it will test what I am aiming at.

My question is:

Does my line of reasoning (regressing, testing beta over time and residual stationarity) make sense? If so, which methods are suitable?


You are right that looking at correlations on their own would be erroneous. This is because time series tend to demonstrate both autocorrelation and cross-correlation over time. e.g. Over the past 10 years, the S&P 500 and the height of a 5-year old child back in 2010 have both since increased - but the two have no theoretical connection to each other.

Instead, you want to test whether such correlations actually have theoretical relevance.

One way of doing this is the two-step Engle-Granger cointegration test. The null hypothesis of this test is no cointegration.

You could implement this test using Python: https://www.statsmodels.org/stable/generated/statsmodels.tsa.stattools.coint.html

As an example, let's consider monthly data for the Euribor benchmark rates obtained from: https://datahub.io/core/euribor

Here is a snippet of the data:


>>> coin_result = ts.coint(rate1, rate2)
>>> coin_result
 array([-3.94714772, -3.36417226, -3.06387292]))

Here, the p-value is 0.15, which implies that no cointegration is present at the 5% level of significance. -2.82 is the cointegration score, while -3.94, -3.36, -3.06 are the respective scores at the 5%, 10%, and 15% levels of significance.


Change points can be difficult in a frequentist framework. Most methods involve identifying the change point as a fixed location, ignoring the uncertainty inherent in estimating it. In addition, fixing a particular parameter (the slope in segment 1) may require a few tricks to get working on many packages.

Change points and fixing parameters come more naturally in a Bayesian context. The R package mcp can flexibly model changes in means and the standard deviation of the residuals, among other things. You may be interested in comparing four models:

model1 = list(y ~ 0 + x)  # No change in slope or sigma
model2 = list(y ~ 0 + x, ~ 0 + x)  # Change in slope only
model3 = list(y ~ 0 + x, ~ 0 + sigma(1))  # Intercept change in sigma only
model4 = list(y ~ 0 + x, ~ 0 + x + sigma(1))  # Change in both

Then fix the first slope to be 1 using a point prior, and do the fit:

prior = list(x_1 = 1)  # fix the slope on x in segment (x_1) to be 1
fit1 = mcp(model1, data, prior)
fit2 = mcp(model2, data, prior)
fit3 = mcp(model3, data, prior)
fit4 = mcp(model4, data, prior)

You can use leave-one-out cross-validation to compare the models' predictive performances or hypothesis() to compare parameter values:

loo::loo_compare(fit1, fit2, fit3, fit4)
hypothesis(fit2, "x_2 < x_1")  # Has the slope flattened in segment 2?

Read more about:

Disclosure: I am the author of the mcp package.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.