Sun Spots

Summary

This demo illustrates how the JMSL Library can be used to quickly build an application that uses ARMA statistical methodology to forecast time series based on historical data. Although the particular time series used here is sun spot frequency per year, such an analysis could apply to numerous types of cyclical time series data such as hurricane frequency, El-nino intensity, or securities prices.

ARMA computes forecasts and probability limits for the forecasts for an ARMA(2, 1) model fit using the method of moments option. With backwardOrigin = 3, ARMA provides forecasts given the data from 1866 to 1869.

Usage

The options for the forecast can be changed by editing the text area for the Confidence level (default = 0.95) and moving the slider for the number of points to predict (default = 11).

Press the "Forecast" button to compute the ARMA forecast - it will appear as a red line extending to the right of the time series with the confidence band filled in yellow.

Click and drag in the chart area to zoom in on the data. Zoom out by pressing the "Reset" button.

JMSL Library Math/Stat Classes

com.imsl.stat.ARMA - this class is used to predict future values of the time series. It is used in the drawGraph() method. Its use is fairly straightforward: just instantiate the class, passing the time series y in the constructor, call compute() and then retrieve the results from the forecast() method. The confidence bounds are obtained from the getDeviations() method. Here is an excerpt:

arma = new ARMA(2, 1, y);
arma
.setRelativeError(0.0);
arma
.setMaxIterations(0);
arma
.compute();
arma
.setConfidence(Double.parseDouble(probField.getText()));
arma
.setBackwardOrigin(3);

double
[][] forecast = arma.forecast(num);
double
[] dev = arma.getDeviations();

JMSL Library Charting Classes

The chart is a standard line chart with symbols. Of note is how the confidence interval of the computed result is plotted. The deviation dev is added and subtracted from the forecast to get the upper bound ul and the lower bound ll. Then the upper region is filled yellow from the boundary down to the minimum value of 0.0. Next the lower region is filled from its boundary down to the minimum and filled with the background color (white). Finally the forecasted values are plotted in red.

upperLimit = new Data(axis, x1, UL);
upperLimit
.setTitle("Upper Limit");
upperLimit
.setDataType(Data.DATA_TYPE_LINE | Data.DATA_TYPE_FILL);
upperLimit
.setReference(min); upperLimit.setFillColor(Color.yellow);
upperLimit
.setFillOutlineColor(Color.white);

lowerLimit
= new Data(axis, x1, ll);
lowerLimit
.setTitle("Lower Limit");
lowerLimit
.setDataType(Data.DATA_TYPE_LINE | Data.DATA_TYPE_FILL);
lowerLimit.setReference(min); lowerLimit.setFillColor(Color.white);
lowerLimit
.setFillOutlineColor(Color.white);

forecastData
= new Data(axis, x1, tmp);
forecastData
.setTitle("Forecast");
forecastData
.setDataType(Data.DATA_TYPE_LINE);
forecastData
.setLineColor(Color.red);

Java Code

This example allows the user to zoom into the chart region. The core of this functionality can be found in the mouse listeners and two paint() methods. When the mouse is first pressed in the chart region, mousePressed() records the coordinates in the from variable, As the mouse is dragged, a green box that highlights the region to zoom into is drawn by the paint() methods. When the mouse button is released, mouseReleased() sets the to variable and the drawGraph() method uses these values as the extents for the axes.

Note how the current coordinates are updated as the mouse moves in the chart area. This is accomplished by the mouseMoved() method as the class implements MouseMotionListener:

public void mouseMoved(MouseEvent e) {
    
axis.mapDeviceToUser(e.getX(), e.getY(), current);
    displayField.setText(getDescription());
}

Finally, notice that the cursor changes to a crosshair cursor when the mouse enters the chart region. This behavior requires that the class implements MouseListener, and these two methods control the cursor changes:

public void mouseEntered(MouseEvent e) {
    setCursor
(new java.awt.Cursor(java.awt.Cursor.CROSSHAIR_CURSOR));
}


public
void mouseExited(MouseEvent e) {
    setCursor
(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
}

Link to Source Code

SunSpots.java This is the main class that extends JFrameChart. The chart and GUI elements are all initialized in the constructor.