5.4 Realized measures of co-volatility

  • Commands, such as rCov(), rThresholdCov(), rBPCov(), rTSCov() and rRTSCov(), also support calculating realized covariance (co-volatility) when using xts objects of multiple assets n

  • Above commands compute covariance matrix of dimensions n×n for each trading day, which can be standardized for obtaining a correlation matrix by setting the argument cor=TRUE

  • For instance, in the bivariate case (assets x and y), the realized covariance (RCOV) for each trading day t is calculated as the sum of the products of synchronized and equally spaced m intraday returns at the K-th sampling frequency

RCOVKt=mj=1r(x)t,jr(y)t,j

  • If the intraday returns of two assets are combined into a single matrix of dimensions m×2, the inner product of this matrix will result in a 2×2 symetric matrix with realized variances on the diagonal and the off–diagonal realized covariances

  • In addition to the issues of microstructure noise and price jumps, two additional problems emerge when computing realized covariance: high–frequency prices are not synchronized over multiple assets and the covariance matrix is not guaranteed to be positive semi–definite

  • As the sampling frequency increases (i.e., the sampling interval shortens), RCOV converges to the integrated covariance (ICOV), assuming no microstructure noise in synchronized returns. However, in practice, microstructure noise causes the diagonal elements to be biased upwards and the off–diagonal elements to be biased downwards as sampling frequency increases

  • Moreover, in the case of non-synchronous returns, an additional bias in realized correlation arises due to so–called Epps effect, further reducing the absolute value of off-diagonal elements

Synchronization schemes and selection of optimal sampling frequency K (neither too low nor too high) are crucial for obtaining an unbiased ICOV estimate, effectively mitigating two primary sources of bias: (a) microstructure noise and (b) the Epps effect

TABLE 5.4: Properties of covariance estimators
Estimator Jump robust Microstructure noise robust Asynchronized data Positive semidefinite
RCOV
RTHRESCOV
RBPCOV
RTTSCOV
RRTTSCOV
  • The majority of estimators are robust to the price jumps, although they are sensitive to microstructure noise (but can become robust if a sufficiently low optimal sampling frequency is chosen) and time sychronization

  • RRTTSCOV is the only one that does not lose data with sparse sampling, it is robust not only to microstructure noise and price jumps but also to asynchronous trading, as it employs the refresh time synchronization scheme (previous tick method), and finally the negative eigenvalues of the covariance matrix are replaced with zeros to deal with non positive semidefiniteness (argument makePsd=TRUE)

  • The first refresh time corresponds to the first time at which both stocks have traded, the subsequent refresh time is defined as the first time when both stocks have again traded, etc.

Example 18. Compute robust two-times scale realized covariance (RTTSRCOV) estimates between Tesla stock and Nasdaq index (object covariance_matrices). Within rRTSCov() command use input as a list of prices tesla and nasdaq, and set the slow time scale to 8 minutes, while keeping the fast time scale at the highest possible sampling frequency of 1 minute. Extract the covariance matrix for the last observed date 2025-03-28. Again employ the same command b to produce correlation_matrices object by setting argument cor=TRUE (default is FALSE).
Solution Copy the code lines below to the clipboard, paste them into an R Script file, and run them.
# Loading R data file (.R) from Google Drive using tweaked URL
load(url("https://drive.google.com/uc?export=download&id=1X0uwaGECIsrz9uZZXvfZjLcYCiTF98mi"))

# Making sure that both objects are structured as xts
tesla <- as.xts(tesla) # structured as xts object
nasdaq <- as.xts(nasdaq) # structured as xts object

# Loading highfrequency package from the library
library(highfrequency) 

# Make sure that both equities have been traded for same dates 
unique_dates1=unique(as.Date(index(tesla))) # 245 days
unique_dates2=unique(as.Date(index(nasdaq))) # 250 days
matching_dates=as.Date(intersect(unique_dates1,unique_dates2)) 

covariance_matrices <- list()
for (i in seq_along(matching_dates)) {
  pData_list <- list(tesla[paste0(matching_dates[i])], nasdaq[paste0(matching_dates[i])])  
  RTTSRCOV <- rRTSCov(pData_list,
                             cor = FALSE,
                             K = 8,  
                             J = 1,
                             eta=9,
                             makePsd=TRUE)
  covariance_matrices[[as.character(matching_dates[i])]] <- RTTSRCOV}

covariance_matrices["2025-03-28"] # extracts covariance matrix for specific date
covariance_matrices[245] # alternative when day is 245

correlation_matrices <- list()
for (i in seq_along(matching_dates)) {
  pData_list <- list(tesla[paste0(matching_dates[i])], nasdaq[paste0(matching_dates[i])])  
  RTTSRCOV <- rRTSCov(pData_list,
                             cor = TRUE,
                             K = 8,  
                             J = 1,
                             eta=9,
                             makePsd=TRUE)
  correlation_matrices[[as.character(matching_dates[i])]] <- RTTSRCOV}

realized_correlations <- sapply(correlation_matrices, function(x) x[1, 2])
realized_correlations <- xts(realized_correlations,order.by = as.Date(matching_dates))
colnames(realized_correlations) <- c("RTTSRCOV")

library(ggplot2)
ggplot(realized_correlations, aes(x = Index)) +
  geom_line(aes(y = RTTSRCOV, color = "RTTSRCOV")) +
  geom_smooth(aes(y = RTTSRCOV, color = "RTTSRCOV (smoothed)"), method = "loess", span = 0.07, se = FALSE, linewidth = 1) +
  labs(x = "", y = "", title = "Realized correlations") +
  scale_color_manual(
    values = c("RTTSRCOV" = "steelblue", "RTTSRCOV (smoothed)" = "orchid")
  ) +
  theme_minimal() +
  theme(
    panel.background = element_rect(fill = "white", color = NA),
    legend.position = c(0.85, 0.1),
    legend.background = element_blank(),
    legend.key = element_blank(),
    legend.title = element_blank(),
    axis.line = element_line(color = "black"))

   

Example 19. Compute robust two-times scale realized covariance (RTTSRCOV) estimates between Tesla stock and Nasdaq index (object covariance_matrices). Within rRTSCov() command use input as a list of prices tesla and nasdaq, and set the slow time scale to 8 minutes, while keeping the fast time scale at the highest possible sampling frequency of 1 minute. Extract the covariance matrix for the last observed date 2025-03-28. Again employ the same command b to produce correlation_matrices object by setting argument cor=TRUE (default is FALSE).
Solution Copy the code lines below to the clipboard, paste them into an R Script file, and run them.
sampling <- c(2:20)
correlation_list <- list()
for (k in sampling) {
for (i in seq_along(matching_dates)) {
  pData_list <- list(tesla[paste0(matching_dates[i])], nasdaq[paste0(matching_dates[i])])  
  RTTSRCOV <- rRTSCov(pData_list,
                             cor = TRUE,
                             K = k,  
                             J = 1,
                             eta=9,
                             makePsd=TRUE)
  correlation_matrices[[as.character(matching_dates[i])]] <- RTTSRCOV
correlations <- xts(sapply(correlation_matrices, function(x) x[1, 2]),order.by = as.Date(matching_dates))
correlation_list[[paste0("K", k)]] <- correlations
}}

all_correlations <- do.call(merge, correlation_list)
colnames(all_correlations) <- names(correlation_list)

# Averaging out realized correlations across days against sampling frequency
correlation_average <- data.frame("AvgCor"=colMeans(all_correlations))
correlation_average$frequency <- sampling

# Plotting the Epps effect
ggplot(correlation_average, aes(x = frequency, y = AvgCor)) +
  geom_line(color = "coral") +
  geom_point(color = "coral", size = 2) +
  labs(x = "Sampling frequency (minutes)", y = "Average realized correlation",title="Epps effect") +
  theme_minimal()