Most, if not all, macroeconomic time series exhibit seasonal patterns. A first step before estimating a model for any time series analyst is to remove the seasonal component. While very common, this step is however difficult to implement, in particular for MATLAB users.
The most accurate tool to deseasonalize time series is the X-13ARIMA-SEATS Seasonal Adjustment Program from Census Bureau. This post simply shows how to implement it based on the amazing (but yet undocumented) work of Stephane Adjemian.
Pre-requisite:
- dseries object (here taken from an installed version of Dynare but if you are not familiar with Dynare you can download the dseries module alone);
- Mac/Linux users must also download the X-13 library.
Let consider the most simple case of Airline data that are available in MATLAB that can be loaded with:
% load Airline data load Data_Airline; |
Then, we simply call the dseries object from Dynare’s libraries and initialize it:
% obtain Dynare directory get_dynare_src = strrep(which('dynare'),'dynare.m',''); % load dseries object addpath([get_dynare_src 'modules\dseries\src\'],[get_dynare_src 'missing\rows_columns\']) initialize_dseries_class(); |
Next, we convert the vector of Airline passengers into a dseries object:
% convert data into dseries object ts = dseries(Data,'1949M1'); |
Finally, we call the exe file of the X-13 lib and pass it arguments as follows:
% create the x13 object o = x13(ts); % adjust options o.transform('function','log'); o.arima('model',' (0 1 1)12'); o.x11('save','(d10)'); % run o.run(); |
Note that this step can be changed based on options that can be found in the Census bureau documentation. Here we consider the default option, combined with 12 lag ARMA process to be consistent with monthly data. This must be adjusted manually by the user.
The seasonal component can be found in:
% extract the multiplicative seasonal pattern season_y = o.results.d10; |
We can simply draw the deseasonalized time series and its original counterpart:
% display results figure; plot(dates,o.y.data,dates,(o.y.data)./(season_y.data)) xlim([min(dates),max(dates)]) datetick('x','mm-yyyy','keeplimits') grid on; |
Note that because the seasonal component is multiplicative, we simply divide our time series with its seasonal component. The full code can be downloaded here.