7
$\begingroup$

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?

$\endgroup$
3
  • $\begingroup$ 4.17.7 Soft-barrier option? $\endgroup$
    – tagoma
    Commented May 27, 2012 at 19:02
  • 3
    $\begingroup$ You seem to have logarithms of squared ratio returns (log_squared_returns) instead of squares of log-returns: sum_squares_1 can be negative. $\endgroup$ Commented May 28, 2012 at 5:56
  • 2
    $\begingroup$ 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 $\endgroup$
    – joelhoro
    Commented Jul 11, 2012 at 14:41

1 Answer 1

4
$\begingroup$

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))
$\endgroup$
2
  • $\begingroup$ 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? $\endgroup$
    – Bob Jansen
    Commented Aug 10, 2014 at 13:15
  • $\begingroup$ Just naively added my 'standard' method. Sorry if this caused any confusion $\endgroup$
    – mike
    Commented Aug 18, 2014 at 11:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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