
The traditional Hodrick-Prescott filter is implemented through the HodrickPrescott class. That implementation decomposes a time series using the model-based approach of the Hodrick-Prescott filter (sum of an I(2) signal and of a white noise, with independent disturbances). The components are estimated by means of the Kalman smoother. That algorithm should be applied on series that don't contain any seasonal and/or erratic component. In practice, a good solution could be the following:
To avoid breaks in the trend-cycle component, the outliers detection module of Tramo-Seats should not allow level shift outliers.
The code below shows that solution
References:
- NbbUtilities.dll
- NbbTs.dll
- NbbMath.dll
- NbbEco.dll
- NbbStat.dll
- NbbTramoSeats.dll
Code:
using Nbb.TimeSeries.SimpleTS;
using Nbb.TramoSeats;
using Nbb.TrendCycle;// External trade statistics: exports
double[] data =
{
9568.3,9920.3,11353.5,9247.5,10114.2,10763.1,8456.1,8071.6,10328,10551.4,10186.1,8821.6,
9841.3,10233.6,10794.6,10289.3,10513.4,10607.6,9707.4,8103.5,10982.6,11836.9,10517.5,9810.5,
10374.8,10855.3,11671.3,11901.2,10846.4,11917.5,11362.8,9314.5,12605.9,12815.1,11254.5,11111.8,
11282.9,11554.5,12935.6,12146.3,11615.3,13214.8,11735.5,9522.3,12694.8,12317.6,11450,11380.9,
10604.6,10972.2,13331.5,11733.1,11284.7,13295.8,11881.4,10374.2,13828,13490.5,13092.2,13184.4,
12398.4,13882.3,15861.5,13286.1,15634.9,14211,13646.8,12224.6,15916.4,16535.9,15796,14418.6,
15044.5,14944.2,16754.8,14254,15454.9,15644.8,14568.3,12520.2,14803,15873.2,14755.3,12875.1,
14291.1,14205.3,15859.4,15258.9,15498.6,15106.5,15023.6,12083,15761.3,16943,15070.3,13659.6,
14768.9,14725.1,15998.1,15370.6,14956.9,15469.7,15101.8,11703.7,16283.6,16726.5,14968.9,14861,
14583.3,15305.8,17903.9,16379.4,15420.3,17870.5,15912.8,13866.5,17823.2,17872,17420.4,16704.4,
15991.5,16583.6,19123.4,17838.8,17335.3,19026.9,16428.6,15337.4,19379.8,18070.5,19563,18190.6,
17658,18437.9,21510.4,17111,19732.7,20221.8
};
TS series = new TS(TSFrequency.Monthly, 1995, 0, data);TramoSeats ts = new TramoSeats();
TramoSpecification tspec = new TramoSpecification();
tspec.CalendarEffect.TradingDaysEffect = TradingDaysOption.Td1Pretest;
tspec.Transformation.Option = DataTransformation.Pretest;
tspec.ModelIdentification.IsEnabled = true;
// Allow only additive outlier
tspec.OutliersDetection.AO=true;// Process TramoSeats
ts.Process(series, tspec, new SeatsSpecification());
// Keep the Trend-Cycle component
TS tc = ts.FinalComponent(CmpType.TrendCycle).
// Define the Hodrick-Prescott filter (with a noise/signal variance ratio = 10000), and apply it on the Trend-Cycle.
HodrickPrescott hp = new HodrickPrescott();
hp.Lambda = 10000;
hp.Decompose(tc);
TS trend= hp.Trend, cycle=hp.Cycle;
That solution implicitly uses backcasts/forecasts of the series that are based on the underlying ARIMA model (I(2) + w.n.), which are seldom optimal. To improve the stability of the trend-cycle decomposition at the extremities of the series, Kaiser-Maravall proposed a different approach . That solution is implemented in the HPArima class. It consists of a pre-processing of the series by Tramo and of a modified canonical decomposition of the estimated model, that splits the Trend-Cycle component in its two parts (see [1]). The components corresponding to the UCARIMA model obtained by that procedure can be estimated by means of the Wiener-Kolmogorov filter or by means of the Kalman smoother.
For reasons of stability, the current implementation uses by default an airline model (which means that the automatic model identification of Tramo is disabled) and the Kalman smoother. In some pathological cases, the decomposition of more general models (obtained by the automatic model identification of Tramo) and/or the use of the Wiener-Kolmogorov filter yield unreliable results. So, these options should be used with caution.
The code below shows the use of the HPArima class
References:
- NbbUtilities.dll
- NbbTs.dll
- NbbMath.dll
- NbbEco.dll
- NbbStat.dll
- NbbTramoSeats.dll
Code:
using Nbb.TimeSeries.SimpleTS;
using Nbb.TramoSeats;
using Nbb.TrendCycle;// External trade statistics: exports
double[] data = ...
TS series = new TS(TSFrequency.Monthly, 1995, 0, data);
// Default HPArima decomposition
Nbb.TramoSeats.HPArima hparima = new HPArima();
HPSpecification hpspec = new HPSpecification();
hpspec.UseDefLambda = false;
hpspec.Lambda=10000;
hparima.Process(series, hpspec);
TS trend1 = hparima.Component(CmpType.Trend), cycle1=hparima.Component(CmpType.Cycle);
// Be aware that no correction is made on the results if the decomposition is applied on the logs of the series
if (hparima.LogTransformation)
{
trend1 = trend1.Exp();
cycle1 = cycle1.Exp();
}// HPArima with a specific TramoSpecification
Tramo tramo = new Tramo();
TramoSpecification spec = new TramoSpecification();
spec.CalendarEffect.TradingDaysEffect = TradingDaysOption.Td1Pretest;
spec.Transformation.Option = DataTransformation.Pretest;
spec.ModelIdentification.IsEnabled = true;
spec.OutliersDetection.AO=true;
tramo.Process(series , spec);
Nbb.TramoSeats.HPArima hparima2 = new HPArima();
hpspec.Method = ComponentsEstimationMethod.WienerKolmogorov;// HPArima with a specific TramoSpecification. You should be ready to catch estimation errors.
try
{
if (hparima2.Process(tramo, hpspec))
{
TS trend2 = hparima2.Component(CmpType.Trend), cycle2=hparima2.Component(CmpType.Cycle);
if (hparima2.LogTransformation)
{
trend2 = trend2.Exp();
cycle2 = cycle2.Exp();
}
}
}
catch
{
}
[1]