I am trying to implement Roger Satchell volatility in Go, but my results do not match reality... I have been at this all day, but cannot find my error. The 30 day Rogers Satchell vol is at 8.75%, but my output is 0.004858435700980119... The formula can be found here: https://portfolioslab.com/tools/rogers-satchell

func getRogersSatchell(class OHLC, period_length int) Volatilities {

    var vol Volatilities

    for i := period_length; i < len(class.close); i++ {

        var sum float64

        for j := i; j > (i - period_length); j-- {

            x1 := math.Log(class.high[j] / class.close[j])
            x2 := math.Log(class.high[j] / class.open[j])
            x3 := math.Log(class.low[j] / class.close[j])
            x4 := math.Log(class.low[j] / class.open[j])

            sum += (x1 * x2) + (x3 * x4)


        volatility := math.Sqrt(sum / float64(period_length))

        vol.rogers_satchell = append(vol.rogers_satchell, volatility)


    return vol
  • 1
    $\begingroup$ Hi: It's not clear to me why you have two loops. You should be looping over $t$ and that's it. That may be causing your problem possibly. $\endgroup$
    – mark leeds
    Sep 28 '21 at 23:59
  • $\begingroup$ @markleeds There are two loops because I am trying to compute rolling volatility, where the period length is 30 days. $\endgroup$ Sep 29 '21 at 23:44
  • $\begingroup$ I see. So maybe that's not your problem. Hopefully Pleb's response clarifies what you did incorrectly. I didn't go through it but it looks useful. Let us know if that doesn't clarify. $\endgroup$
    – mark leeds
    Sep 30 '21 at 3:24

An answer with R and pseudo-code:

As pointed out by @markleeds, there is no need for two for-loops, since you can vectorize the outer loop. You only need the last for-loop if you want to do rolling Roger-Satchell volatility estimates. I cannot code in Go, but I can provide you with some pseudo-code.

Let your OHLC data be defined as $X \in \mathbb{R}^{T\times 4}$, where each column is respectively the daily open, high, low and close. That is, $X$ is a matrix with the time-dimension, $t=1,\ldots,T$, as the rows and OHLC as the columns. Constructing some pseudo-code, your Golang function should have similar structure as the snippet below:

function RSVol(OHLC, n){

  ""Initialise RSVol to store numeric values:""
  RSVol = Vector()
  ""These are now vectors of dimension T x 1:""
  open = OHLC[,1] 
  high = OHLC[,2] 
  low = OHLC[,3] 
  close = OHLC[,4] 

  ""the inner part of the mean:""
  inner = log(high/close) * log(high/open) + log(low/close) * log(low/open)

  ""Doing a rolling mean depending on n:""
  for(i=n:length(open); i++){

    RSVol[i] =  sqrt(mean(inner[i+1-n:i])



Implementing the above pseudo-code in R and comparing my function to the Rogers Satchell estimator in the TTR package produce the same results:


#first 6 rolling estimates with n=10.

myfunc <- RSVol(OHLC,10)[11:16] 
TTR_RSVol <- volatility(OHLC, n = 10, calc = "rogers.satchell", N = 1, mean0 = FALSE)[11:16]

data.frame(myfunc = myfunc, TTR_func = TTR_RSVol)


The near identical results seen above, gives some validity to my pseudo-code and R code. I have provided my R function in an appendix below. I hope this helps with the proper implementation of your Rogers Satchell estimator in Go. If not, then please edit your question and provide some example data or where to get it. Then we can do some output matching between the constructed functions.

Appendix: R code

I have provided my R code below for better understanding.

RSVol <- function(OHLC, n){

  open <- OHLC[,1]
  high <- OHLC[,2]
  low <- OHLC[,3]
  close <- OHLC[,4]

  RSVol <- numeric()

  firstpart <- log(high/close) * log(high/open)
  lastpart <- log(low/close) * log(low/open)

  inner <- firstpart + lastpart

  #calculating rolling mean:

  for(i in n:nrow(OHLC)){

    RSVol[i] <- sqrt(mean(inner[(i+1-n):i]))

  • $\begingroup$ Hi @StevenSemeraro if my answer helped you out, would you then please consider accepting it, by clicking the green tick below the scores? :-) $\endgroup$
    – Pleb
    Dec 13 '21 at 22:04

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.