Page 1 of 1

(Co)Variance estimates with Gaussian kernel

Posted: Mon Jun 08, 2015 7:36 am
by Thomasms90
Hi

I'm interested in estimating time varying variances and covariances using a simple two sided gaussian/normal kernel function. However it is not one of the built-in options.

Can anyone direct me towards how to specify the "User Kernel Vector" in order to do this if possible? Or pointers on how to implement a program that may do it.

In my case I'm using daily data and want a Gaussian Kernel with a bandwidth of 250days.

Best regards,
Thomas

Re: (Co)Variance estimates with Gaussian kernel

Posted: Wed Jun 10, 2015 8:30 am
by Thomasms90
I have tried to come up with a program to calculate the time varying standard deviation of a return series. Code is below.

It seems to do the job pretty good, however it's incredibly inefficient. I have over 9000 observations leading to around 170 million iterations. Execution time is around 10-12mins on my laptop per series and ultimately I have hundreds of series I need to run.

Is there no other way to do this more efficiently? I've been trying to think of a way to weight each observation by a full normal distribution from the built-in function, but can't come up with a solution.

Code: Select all

stom(g_r, ret) !obs = @rows(ret) !h = 250/!obs vector(!obs) kernelvec for !i = 1 to !obs !tau = !i / !obs !sum = 0 !kerndev = 0 for !j = 1 to !obs !z = !j/!obs - !tau !kernel = (1 / sqr( 2 * @acos(-1) ) * exp( - ( !z / !h ) ^ 2 / 2)) / (!h*!obs) !sum = !sum + !kernel next !j for !j = 1 to !obs !z = !j/!obs - !tau !kernel = (1 / sqr( 2 * @acos(-1) ) * exp( - ( !z / !h ) ^ 2 / 2)) / (!h*!obs) / !sum !kerndev = !kerndev + !kernel * ret(!j) ^2 next !i kernelvec(!i) = sqr(!kerndev) next !i mtos(kernelvec, kernel250)

Re: (Co)Variance estimates with Gaussian kernel

Posted: Wed Jun 10, 2015 1:10 pm
by EViews Glenn
Without commenting on the desired calculations...

Here's a snippet which simulates data for 10000 observations, performs the desired calculations, and times the process. Note that where possible I use the series generation tools rather than observation loops. Looking at it right now, are a couple of other optimizations we could do, but this should be good enough to hold you over.

Code: Select all

rndseed 1 workfile u 10000 series ret = nrnd series ret2 = ret^2 tic !obs = @obs(ret) !h = 250/!obs series rollstd for !i=1 to @obs(ret) series z = (@trend+1-!i)/!obs series w = @dnorm(z/!h) !kernel = @inner(w, ret2) / @sum(w) smpl if (@trend+1=!i) rollstd = @sqrt(!kernel) smpl @all next !elapsed = @toc table(1,1) time time(1,1) = !elapsed
The original code with the same simulated data process and a timer

Code: Select all

rndseed 1 workfile u 10000 series g_r = nrnd tic stom(g_r, ret) !obs = @rows(ret) !h = 250/!obs vector(!obs) kernelvec for !i = 1 to !obs !tau = !i / !obs !sum = 0 !kerndev = 0 for !j = 1 to !obs !z = !j/!obs - !tau !kernel = (1 / sqr( 2 * @acos(-1) ) * exp( - ( !z / !h ) ^ 2 / 2)) / (!h*!obs) !sum = !sum + !kernel next !j for !j = 1 to !obs !z = !j/!obs - !tau !kernel = (1 / sqr( 2 * @acos(-1) ) * exp( - ( !z / !h ) ^ 2 / 2)) / (!h*!obs) / !sum !kerndev = !kerndev + !kernel * ret(!j) ^2 next !i kernelvec(!i) = sqr(!kerndev) next !i mtos(kernelvec, kernel250) !elapsed = @toc table(1,1) time
Timings will obviously vary, but on my computer the former took 9.1 seconds, while the original took 267.6 seconds.

Re: (Co)Variance estimates with Gaussian kernel

Posted: Wed Jun 10, 2015 3:40 pm
by Thomasms90
Thanks a bunch Glenn! Took a bit to figure out how it worked, but its a genious solution.

Reduced my complete execution time by a factor 115.