Take the 2-minute tour ×
Quantitative Finance Stack Exchange is a question and answer site for finance professionals and academics. It's 100% free, no registration required.

I have implemented a function for calculating historical volatility using close the close method as described by Haug on page 166.

When I implemented the formula given by Haug, it resulted in some negative values for the variance. The data I am using is not suspect, so the fault must lie in either:

  • my implementation or
  • the formula itself.

Here is a rough sketch of my implementation function (in Python)

# close_prices is a time sorted list of pricedata objects
# returns a list of calculated volatilities
def calc_volatility(close_prices, period):
    startpos, stoppos, raw_vols = (0, period, [])
    while True:
        subset = close_prices[startpos:stoppos+1]
        period_returns      = [ subset[i].close_price/subset[i-1].close_price for i in range(1,len(subset)) ]
        log_returns         = [ math.log(x) for x in period_returns ]
        log_squared_returns = [ math.log(pow(x,2)) for x in period_returns ]

        sum_squares_1 = sum( log_squared_returns ) / (period-1)
        sum_squares_2 = pow( sum( log_returns ), 2) / (period * (period -1))

        variance = sum_squares_1 - sum_squares_2
        print "ss1: {0} - ss2: {1}. Variance: {2}".format(sum_squares_1, sum_squares_2, variance)

        volatility = math.sqrt(variance)

        raw_vols.append (volatility)

        startpos += period
        stoppos  += period

        if stoppos >= len(close_prices):
            break

    return raw_vols

Is there something wrong in my implementation, or is the formula I am using, incorrect?

share|improve this question
    
4.17.7 Soft-barrier option? –  edouard May 27 '12 at 19:02
1  
You seem to have logarithms of squared ratio returns (log_squared_returns) instead of squares of log-returns: sum_squares_1 can be negative. –  Vincent Zoonekynd May 28 '12 at 5:56
    
For better efficiency, you could write log_squared_returns = [ pow(x,2) for x in log_returns ] and that would have prevented your error mentionned by @VincentZoonekynd –  joelhoro Jul 11 '12 at 14:41

1 Answer 1

I have a different solution, which calculates the vol for a list of prices.

import math

#workout volatility
def perc_change(price_list):
 return [(v / price_list[abs(i-1)])-1 for i, v in enumerate(price_list)]

def variance(price_list):
 perc = perc_change(price_list)
 avg = average(perc)
 return [(x - avg)**2 for x in perc]

def average(x):
 return sum(x)/len(x)


var = variance(list_of_prices)

volatility = math.sqrt(average(var))
share|improve this answer
    
Hi mike, welcome to quant.SE! This is the standard method to calculate the variance. However, that's not Haug's method. Are you saying that method doesn't work at all, or something else? –  Bob Jansen Aug 10 at 13:15
    
Just naively added my 'standard' method. Sorry if this caused any confusion –  mike Aug 18 at 11:17

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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