Moving Sample Methods


We have received numerous queries regarding how to compute statistics on a moving window of a fixed sample size. There are currently no built-in function to do this, except for the simple moving averages @movav() and moving sums @movsum(). There is an example of rolling ADF test in Chapter 7 of the Command and Programming Reference which computes a test statistics on a moving sample of fixed size. Since many users are having difficulties in modifying the program to meet their needs, we provide a detailed tutorial and further examples.

Moving the sample using FOR loops

In order to write a program for moving windows, you must understand how to use for loops in EViews. FOR loops are described in the Command and Programming Reference, Chapter 6, Control of Execution. In a program for moving windows, the for loop is used to shift the sample one observation at a time. For example, consider the following piece of code:
' create workfile
workfile movsmp u 1 100

' set window size
!window = 20

' get size of workfile
!length = @obsrange

' compute stats for each window
for !i = 1  to  !length-!window+1
	smpl @first+!i-1 @first+!i+!window-2
	' (code to do stuff for each subsample)
next
The first line creats an undated workfile with 100 observations. The next block sets the size of the window, in this case 20 observations. !window (a variable beginning with the symbol !) is an example of a control variable, which is a temporary scalar variable that is not stored in the workfile. The third block assigns the length of the current workfile range to the control variable !length. The final block is the for loop that moves the window one observation at a time. If you substitute the control variable !i in the smpl statement, you will find that the for loop block is a shorthand for and equivalent to the following sets of commands:
	smpl 1+1-1 1+1+20-2
	' (code to do stuff for each subsample)
	smpl 1+2-1 1+2+20-2
	' (code to do stuff for each subsample)
	smpl 1+3-1 1+3+20-2
	' (code to do stuff for each subsample)
	...
	smpl 1+(100-20)-1 1+(100-20)+20-2
	' (code to do stuff for each subsample)
	smpl 1+(100-20+1)-1 1+(100-20+1)+20-2
	' (code to do stuff for each subsample)
or
	smpl 1 20
	' (code to do stuff for each subsample)
	smpl 2 21
	' (code to do stuff for each subsample)
	smpl 3 22
	' (code to do stuff for each subsample)
	...
	smpl 80 99
	' (code to do stuff for each subsample)
	smpl 81 100
	' (code to do stuff for each subsample)

Storing results from each subsample

In order to write a working program, you need to add two more things to the program: a containter to hold the moving statistics and code to compute the statistics for each sample (in the for loop). For containers, you can either use a series or a matrix/vector. There is a subtle difference between using the two objects, which we explain with an example. Suppose you want to compute the standard deviation of a series x over a moving window. The following block of code (assuming !window and !length are defined) stores the results in a matrix:
' declare matrix to store results
matrix(!length-!window+1,1) movstd

' compute stats for each window
for !i = 1  to  !length-!window+1
	smpl @first+!i-1 @first+!i+!window-2
	' store std.dev. in matrix
	movstd(!i,1) = @stdev(x)
next
To store the result in a matrix simply assign the statistic to a specified row and column of the matrix. Now consider the following code which is intended to store the results in a series:
' declare series to store results
series serstd

' compute stats for each window
for !i = 1  to  !length-!window+1
	smpl @first+!i-1 @first+!i+!window-2
	' store std.dev. in series
	serstd = @stdev(x)
next
The code "almost" works, except at the end of the sample. When you assign @stdev() to a matrix element, the function returns a scalar. However, if you assign @stdev() to a series, the function returns a series. In this example, it will return a series filled with the standard deviation in the current subsample. Therefore the series version is doing the following at each iteration in the loop:
!i=1: fill observations 1-20 of serstd with the standard deviation of x for the sample 1-20.
!i=2: fill observations 2-21 of serstd with the standard deviation of x for the sample 2-21.
...
!i=81: fill observations 81-100 of serstd with the standard deviation of x for the sample 81-100.
This means that the values in serstd from the previous subsample except the first are overwritten by the results from the next subsample. So the series serstd will contain the same results as the matrix version, except at the end which is filled with the standard deviation from the last subsample. A fix for this "last subsample problem" is to modify the code as follows:
' declare series to store results
series serstd

' compute stats for each window
for !i = 1  to  !length-!window+1
	smpl @first+!i-1 @first+!i+!window-2
	' first store std.dev. in temporary scalar
	!std = @stdev(x)
	' reset to one observation sample 
	smpl @first+!i-1 @first+!i-1
	' and assign to series
	serstd = !std
next
This code first stores the standard deviation in a control variable !std. Then it resets the sample to the beginning of each subsample and assigns the value to one observation in the series. If you want to store the result at the end of each subsample, you simply modify the second smpl statement to
	' reset to one observation sample at end
	smpl @first+!i+!window-2 @first+!i+!window-2

Application: rolling forecasts

The dynamic forecasts from the Equation Proc produces multi-period forecasts with the same set of estimated parameters. Suppose instead that you want to produce multi-period forecasts by reestimating the parameters as new data become available. To be more specific, suppose you want to produce forecasts up to 4 periods ahead from each subsample where each subsample is moved 4 periods at a time. Your first code is likely to be as follows:
' set window size
!window = 20

' get size of workfile
!length = @obsrange

' declare equation for estimation
equation eq1

' declare series to store results
series yhat		' point estimates
series yhat_se		' forecast std.err.

' set step size
!step = 4

' move sample !step obs at a time
for !i = 1  to  !length-!window+1-!step step !step
	' set sample to estimation period
	smpl @first+!i-1 @first+!i+!window-2
	' estimate equation
	eq1.ls y c y(-1) y(-2)
	' reset sample to forecast period
	smpl @first+!i+!window-1 @first+!i+!window-2+!step
	' make forecasts
	eq1.forecast yhat yhat_se
next
The main problem with this code is the last line inside the loop where you store the forecasts. In the code above, the forecast series will be overwritten each time in the loop and at the end of the program yhat and yhat_se will contain forecasts only from the last subsample. Important note: if you look at the forecast series, you will find that the series is filled with numbers for the entire sample. By default, EViews fills the forecast series with actual values of the dependent variable outside the forecast sample.

The fix is to store the forecasts in a temporary series first (this series will be overwritten each time in the loop) and then copy over the relevant data to a separate series.

' set window size
!window = 20

' get size of workfile
!length = @obsrange

' declare equation for estimation
equation eq1

' declare series for final results
series yhat		' point estimates
series yhat_se		' forecast std.err.

' set step size
!step = 4

' move sample !step obs at a time
for !i = 1  to  !length-!window+1-!step step !step
	' set sample to estimation period
	smpl @first+!i-1 @first+!i+!window-2
	' estimate equation
	eq1.ls y c y(-1) y(-2)
	' reset sample to forecast period
	smpl @first+!i+!window-1 @first+!i+!window-2+!step
	' make forecasts in temporary series first
	eq1.forecast(f=na) tmp_yhat tmp_se
	' copy data in current forecast sample
	yhat = tmp_yhat
	yhat_se = tmp_se
next
The f=na option for the forecast command fills the forecast series outside the forecast sample with NAs.

[rollfcst1.prg]
Rolling forecast with coefficient update. Plots actual and rolling forecasts with confidence bounds.
[rollfcst2.prg]
Comparison of rolling forecasts with and without coefficient update.
[rollfcst3.prg]
Rolling forecast using the sspace object.

(revised 11/3/2000 h)