Setup

This report shall serve as the validation for the related Pinescript indicator that uses the VWMA based ATR for volatility regime identification. The validation was completed by using the R Quantmod library to compare the results of 3 indicators on SPY against the VIX. For the purpose of this analysis, the CBOE Volatility Index (VIX) shall serve as the benchmark representing the true volatility level by comparing its linear relationship with the indicators: the Larry Williams VIX Fix, the VWMA based ATR that is the subject of this report, and a regular ATR that is normalized to price.

suppressMessages(library(quantmod))
options(scipen = 999)
getSymbols(Symbols = c('^VIX', 'SPY'))

Larry Williams VIX Fix

The VIX Fix is an approximation of the VIX that was developed by technical trader Larry Williams. Based on the analysis below, a strong positive linear relationship exists between the VIX Fix and the Actual VIX.

# Larry Williams VIX Fix
VixFixLW <- (rollmax(x = Cl(SPY), k = 22) - Lo(SPY)) / 
  rollmax(x = Cl(SPY), k = 22) 
test <- na.omit(merge.xts(VixFixLW, Cl(VIX)))
colnames(test) <- c('VixFix', 'VIX')
mod <- lm(test$VIX ~ test$VixFix)
plot(x = as.numeric(test$VixFix), y = as.numeric(test$VIX),
     xlab = 'VIX Fix', ylab = 'Actual VIX') + abline(mod)

## integer(0)
cor(x = test$VixFix, y = test$VIX)
##              VIX
## VixFix 0.7800489
summary(mod)
## 
## Call:
## lm(formula = test$VIX ~ test$VixFix)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -20.471  -3.305  -0.968   2.341  39.519 
## 
## Coefficients:
##             Estimate Std. Error t value            Pr(>|t|)    
## (Intercept)  11.3240     0.1324   85.56 <0.0000000000000002 ***
## test$VixFix 255.6002     3.0571   83.61 <0.0000000000000002 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 5.617 on 4498 degrees of freedom
## Multiple R-squared:  0.6085, Adjusted R-squared:  0.6084 
## F-statistic:  6990 on 1 and 4498 DF,  p-value: < 0.00000000000000022

Modified ATR Using the Volume Weighted Moving Average of the True Range

A stronger positive relationship exists between the Modified VWMA ATR and VIX than previously observed between the VIX Fix and VIX.

# Modified ATR Using the Volume Weighted Moving Average of the True Range
ModifiedATR <- VWMA(price = TR(HLC(SPY))$tr, volume = Vo(SPY), n = 14) / Cl(SPY)
test2 <- na.omit(merge.xts(ModifiedATR, Cl(VIX)))
colnames(test2) <- c('ModifiedATR', 'VIX')
mod2 <- lm(test2$VIX ~ test2$ModifiedATR)
plot(x = as.numeric(test2$ModifiedATR), y = as.numeric(test2$VIX),
     xlab = 'Modified VWMA ATR', ylab = 'VIX') + abline(mod2)

## integer(0)
cor(x = test2$ModifiedATR, y = test2$VIX)
##                   VIX
## ModifiedATR 0.9150521
summary(mod2)
## 
## Call:
## lm(formula = test2$VIX ~ test2$ModifiedATR)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -22.3208  -2.1199  -0.4349   1.8897  18.3507 
## 
## Coefficients:
##                    Estimate Std. Error t value            Pr(>|t|)    
## (Intercept)         7.75125    0.09621   80.56 <0.0000000000000002 ***
## test2$ModifiedATR 797.10669    5.23468  152.27 <0.0000000000000002 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 3.618 on 4505 degrees of freedom
## Multiple R-squared:  0.8373, Adjusted R-squared:  0.8373 
## F-statistic: 2.319e+04 on 1 and 4505 DF,  p-value: < 0.00000000000000022

Standard ATR Normalized to Price

The strongest positive relationship was found between the Normalized ATR and VIX:

# Standard ATR Normalized to Price
NormalizedATR <- ATR(HLC(SPY), n = 14)$atr / Cl(SPY)
test3 <- na.omit(merge.xts(NormalizedATR, Cl(VIX)))
colnames(test3) <- c('NormalizedATR', 'VIX')
mod3 <- lm(test3$VIX ~ test3$NormalizedATR)
plot(x = as.numeric(test3$NormalizedATR), y = as.numeric(test3$VIX),
     xlab = 'Normalized ATR', ylab = 'VIX') + abline(mod3)

## integer(0)
cor(x = test3$NormalizedATR, y = test3$VIX)
##                     VIX
## NormalizedATR 0.9399473
summary(mod3)
## 
## Call:
## lm(formula = test3$VIX ~ test3$NormalizedATR)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -18.1044  -1.9297  -0.5214   1.6099  24.9310 
## 
## Coefficients:
##                      Estimate Std. Error t value            Pr(>|t|)    
## (Intercept)           6.60938    0.08509   77.67 <0.0000000000000002 ***
## test3$NormalizedATR 947.36971    5.12543  184.84 <0.0000000000000002 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 3.062 on 4505 degrees of freedom
## Multiple R-squared:  0.8835, Adjusted R-squared:  0.8835 
## F-statistic: 3.416e+04 on 1 and 4505 DF,  p-value: < 0.00000000000000022

Conclusion

Why opt for the Modified VWMA ATR if the regular ATR is a better fit?