Example 3: Forecasting

Consider the Wolfer Sunspot Data (Anderson 1971, p. 660) consisting of the number of sunspots observed each year from 1749 through 1924. The data set for this example consists of the number of sunspots observed from 1770 through 1869. An ARMA(2,1) model is fitted to these data using the Method of Moments. With BackwardOrigin = 3, the Forecast method is used to obtain forecasts starting from 1866, 1867, 1868, and 1869, respectively. Note that the values in the first row of the matrix returned by this method are the one-step ahead forecasts for 1867, 1868, ..., 1870. The values in the second row are the two-step ahead forecasts for 1868, 1869, ..., 1871, etc.

Method GetForecast is used to compute the one-step ahead forecasts setting BackwardOrigin = 10. This obtains the one-step ahead forecasts for the last 10 observations in the series, i.e. years 1860-1869, plus the next 5 years. The upper 90% confidence limits are computed for these forecasts using the GetDeviations method.

using System;
using Imsl.Stat;
using PrintMatrix = Imsl.Math.PrintMatrix;
using PrintMatrixFormat = Imsl.Math.PrintMatrixFormat;

public class ARMAEx3
{
    public static void  Main(String[] args)
    {
        double[] z = new double[]{  100.8, 81.6, 66.5, 34.8, 30.6, 
                                     7, 19.8, 92.5, 154.4, 125.9, 
                                     84.8, 68.1, 38.5, 22.8, 10.2,
                                     24.1, 82.9, 132, 130.9, 118.1, 
                                     89.9, 66.6, 60, 46.9, 41,
                                     21.3, 16, 6.4, 4.1, 6.8,
                                     14.5, 34, 45, 43.1, 47.5, 
                                     42.2, 28.1, 10.1, 8.1, 2.5, 
                                     0, 1.4, 5, 12.2, 13.9, 
                                     35.4, 45.8, 41.1, 30.4, 23.9, 
                                     15.7, 6.6, 4, 1.8, 8.5,
                                     16.6, 36.3, 49.7, 62.5, 67,
                                     71, 47.8, 27.5, 8.5, 13.2, 
                                     56.9, 121.5, 138.3, 103.2, 85.8, 
                                     63.2, 36.8, 24.2, 10.7, 15, 
                                     40.1, 61.5, 98.5, 124.3, 95.9, 
                                     66.5, 64.5, 54.2, 39, 20.6, 
                                     6.7, 4.3,  22.8, 54.8, 93.8,
                                     95.7, 77.2, 59.1, 44, 47,  
                                     30.5, 16.3, 7.3, 37.3, 73.9};
        double[,] printEstimates = new double[1,4];
        PrintMatrixFormat pmf = new PrintMatrixFormat();
        PrintMatrix pm        = new PrintMatrix();
        pm.SetColumnSpacing(3);
		
        ARMA arma = new ARMA(2, 1, z);
        arma.RelativeError = 0.0;
        arma.MaxIterations = 0;
        arma.Compute();
		
        printEstimates[0,0] = arma.Constant;
        double[] ar = arma.GetAR();
        printEstimates[0,1] = ar[0];
        printEstimates[0,2] = ar[1];
        double[] ma = arma.GetMA();
        printEstimates[0,3] = ma[0];
        String[] estimateLabels = {"Constant", "AR(1)", "AR(2)", "MA(1)"};
        pmf.SetColumnLabels(estimateLabels);
        pmf.NumberFormat = "0.0000";
        pm.SetTitle("ARMA ESTIMATES");
        pm.Print(pmf, printEstimates);
		
        String[] labels = new String[]{"From 1866", 
                                          "From 1867", 
                                          "From 1868", 
                                          "From 1869"};
        pmf.SetColumnLabels(labels);
        pmf.FirstRowNumber = 1;
        pmf.NumberFormat = "00.0";
        arma.BackwardOrigin = 3;
        new PrintMatrix("FORECASTS").Print(pmf, arma.Forecast(5));
		
        double[,] printTable = new double[15,4];
        /* FORECASTING - An example of forecasting using the ARMA estimates
         * In this case, forecasts are returned for the last 10 values in the 
         * series followed by the forecasts for the next 5 values.
         */
        String[] forecastLabels={"Observed", "Forecast", 
                                    "Residual", "UCL(90%)"};
        pmf.SetColumnLabels(forecastLabels);
        int backOrigin = 10;
        int n_forecast = 5;
        arma.BackwardOrigin = backOrigin;
        arma.Confidence = 0.9;
        double[] forecasts  = arma.GetForecast(n_forecast);
        double[] deviations = arma.GetDeviations();
        for(int i=0; i<backOrigin; i++)
        {
            printTable[i,0] = z[z.Length-backOrigin+i];
            printTable[i,1] = forecasts[i];
            printTable[i,2] = z[z.Length-backOrigin+i]-forecasts[i];
            printTable[i,3] = forecasts[i] + deviations[0];
        }
        for(int i=backOrigin; i<n_forecast+backOrigin; i++)
        {
            printTable[i,0] = Double.NaN;
            printTable[i,1] = forecasts[i];
            printTable[i,2] = Double.NaN;
            printTable[i,3] = forecasts[i] + deviations[i-backOrigin];
        }
        pmf.FirstRowNumber = 1869-backOrigin+1;
        pmf.NumberFormat = "000.0";
        pm.SetTitle("ARMA ONE-STEP AHEAD FORECASTS");
        pm.Print(pmf, printTable);

    }
}

Output

               ARMA ESTIMATES
    Constant    AR(1)    AR(2)     MA(1)    
0   15.5440    1.2443   -0.5751   -0.1241   

                   FORECASTS
   From 1866  From 1867  From 1868  From 1869  
1    18.3       16.6       55.2       83.7     
2    28.9       32.0       62.8       77.2     
3    41.0       45.8       61.9       63.5     
4    49.9       54.1       56.5       50.1     
5    54.1       56.6       50.2       41.4     

           ARMA ONE-STEP AHEAD FORECASTS
       Observed   Forecast   Residual   UCL(90%)   
1860    095.7      100.7      -005.0     128.6     
1861    077.2      081.3      -004.1     109.2     
1862    059.1      057.1       002.0     084.9     
1863    044.0      044.4      -000.4     072.3     
1864    047.0      036.4       010.6     064.2     
1865    030.5      047.4      -016.9     075.3     
1866    016.3      028.6      -012.3     056.4     
1867    007.3      019.8      -012.5     047.7     
1868    037.3      016.8       020.5     044.7     
1869    073.9      055.2       018.7     083.1     
1870    NaN        083.7       NaN       111.6     
1871    NaN        077.2       NaN       124.5     
1872    NaN        063.5       NaN       120.2     
1873    NaN        050.1       NaN       109.4     
1874    NaN        041.4       NaN       100.8     


Link to C# source.