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.
' 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) nextThe 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:
orsmpl 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)
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)
' 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) nextTo 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) nextThe 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.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:
!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.
' 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 nextThis 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
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.' 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 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 nextThe f=na option for the forecast command fills the forecast series outside the forecast sample with NAs.
(revised 11/3/2000 h)