library(PerformanceAnalytics) test_that("SmoothingIndex successfully demeans returns yielding mathematically correct ARMA estimates (fixes #86)", { skip_on_cran() # Reproduce reporter's highly off-center synthetic dataset set.seed(12345) unsmooth <- rnorm(25000, mean = 3, sd = 1.5) # Smooth them with theoretically true thetas = c(0.5, 0.3, 0.2) smooth <- stats::filter(unsmooth, c(0.5, 0.3, 0.2), sides = 1) # Ignore NAs generated by filter() lagging smooth_clean <- na.omit(as.numeric(smooth)) # 1. Manually evaluate the corrected arima fit on demeaned data fit_right <- arima(smooth_clean - mean(smooth_clean, na.rm = TRUE), c(0, 0, 2), include.mean = FALSE) thetas_right <- c(1, coef(fit_right)) / (1 + sum(coef(fit_right))) expected_thetas <- round(thetas_right, 2) # Assert that the theoretical math aligns perfectly with the reporter's evaluation (0.50, 0.30, 0.20) expect_equal(as.numeric(expected_thetas), c(0.50, 0.30, 0.20)) # 2. Evaluate the PerformanceAnalytics method implementation # The smoothing index evaluates sum(thetas^2). # If thetas are (0.50, 0.30, 0.20), sum(thetas^2) = 0.25 + 0.09 + 0.04 = 0.38. si <- SmoothingIndex(smooth_clean, MIN=2, MAX=2) # si evaluates sum(xi^2) natively. expect_equal(as.numeric(si), 0.38, tolerance = 1e-2) })