diff --git a/src/forecast/forecast.h b/src/forecast/forecast.h index 8634d80192..bb7b200176 100644 --- a/src/forecast/forecast.h +++ b/src/forecast/forecast.h @@ -2621,9 +2621,11 @@ class ForecastSolver : public Solver { } Forecast_SmapeAlfa = t; - // Initialize the smape weight array + // Initialize the smape weight array. + // Must fill the full array (matching ForecastSolver::initialize), otherwise + // entries above the old hardcoded bound stay stale when this setter runs. weight[0] = 1.0; - for (int i = 0; i < 299; ++i) + for (int i = 0; i < MAXBUCKETS - 1; ++i) weight[i + 1] = weight[i] * Forecast_SmapeAlfa; } @@ -3041,6 +3043,17 @@ class ForecastSolver : public Solver { /* An array with weights for history buckets. */ static double weight[MAXBUCKETS]; + /* Bounds-safe accessor for the smape weight array. + * The number of history buckets can exceed MAXBUCKETS (e.g. weekly or daily + * buckets over the default 10-year horizon). Because the weights decay + * exponentially, weight[>= MAXBUCKETS] is numerically ~0, so clamping the + * index is behavior-preserving and avoids an out-of-bounds read. */ + static inline double smapeWeight(long idx) { + if (idx < 0) idx = 0; + if (idx >= MAXBUCKETS) idx = MAXBUCKETS - 1; + return weight[idx]; + } + /* Number of warmup periods. * These periods are used for the initialization of the algorithm * and don't count towards measuring the forecast error. diff --git a/src/forecast/timeseries.cpp b/src/forecast/timeseries.cpp index 103600f996..9a54edf5cd 100644 --- a/src/forecast/timeseries.cpp +++ b/src/forecast/timeseries.cpp @@ -352,8 +352,8 @@ ForecastSolver::Metrics ForecastSolver::MovingAverage::generateForecast( if (i >= solver->getForecastSkip() && i < count && fabs(avg + actual) > ROUNDING_ERROR) { error_smape += - fabs(avg - actual) / fabs(avg + actual) * weight[count - i]; - error_smape_weights += weight[count - i]; + fabs(avg - actual) / fabs(avg + actual) * smapeWeight(count - i); + error_smape_weights += smapeWeight(count - i); } } @@ -513,14 +513,14 @@ ForecastSolver::Metrics ForecastSolver::SingleExponential::generateForecast( true); } } - sum_12 += df_dalfa_i * (history_i - f_i) * weight[count - i]; - sum_11 += df_dalfa_i * df_dalfa_i * weight[count - i]; + sum_12 += df_dalfa_i * (history_i - f_i) * smapeWeight(count - i); + sum_11 += df_dalfa_i * df_dalfa_i * smapeWeight(count - i); if (i >= solver->getForecastSkip()) { - error += (f_i - history_i) * (f_i - history_i) * weight[count - i]; + error += (f_i - history_i) * (f_i - history_i) * smapeWeight(count - i); if (fabs(f_i + history_i) > ROUNDING_ERROR) { error_smape += - fabs(f_i - history_i) / (f_i + history_i) * weight[count - i]; - error_smape_weights += weight[count - i]; + fabs(f_i - history_i) / (f_i + history_i) * smapeWeight(count - i); + error_smape_weights += smapeWeight(count - i); } } } @@ -778,24 +778,24 @@ ForecastSolver::Metrics ForecastSolver::DoubleExponential::generateForecast( (1 - gamma) * d_trend_d_gamma; d_forecast_d_alfa = d_constant_d_alfa + d_trend_d_alfa; d_forecast_d_gamma = d_constant_d_gamma + d_trend_d_gamma; - sum11 += weight[count - i] * d_forecast_d_alfa * d_forecast_d_alfa; - sum12 += weight[count - i] * d_forecast_d_alfa * d_forecast_d_gamma; - sum22 += weight[count - i] * d_forecast_d_gamma * d_forecast_d_gamma; - sum13 += weight[count - i] * d_forecast_d_alfa * + sum11 += smapeWeight(count - i) * d_forecast_d_alfa * d_forecast_d_alfa; + sum12 += smapeWeight(count - i) * d_forecast_d_alfa * d_forecast_d_gamma; + sum22 += smapeWeight(count - i) * d_forecast_d_gamma * d_forecast_d_gamma; + sum13 += smapeWeight(count - i) * d_forecast_d_alfa * (history_i - constant_i - trend_i); - sum23 += weight[count - i] * d_forecast_d_gamma * + sum23 += smapeWeight(count - i) * d_forecast_d_gamma * (history_i - constant_i - trend_i); if (i >= solver ->getForecastSkip()) // Don't measure during the warmup period { error += (constant_i + trend_i - history_i) * - (constant_i + trend_i - history_i) * weight[count - i]; + (constant_i + trend_i - history_i) * smapeWeight(count - i); if (fabs(constant_i + trend_i + history_i) > ROUNDING_ERROR) { error_smape += fabs(constant_i + trend_i - history_i) / fabs(constant_i + trend_i + history_i) * - weight[count - i]; - error_smape_weights += weight[count - i]; + smapeWeight(count - i); + error_smape_weights += smapeWeight(count - i); } } } @@ -1139,20 +1139,20 @@ ForecastSolver::Metrics d_forecast_d_beta = (d_L_d_beta + d_T_d_beta) * S_i[cycleindex] + (L_i + T_i) * d_S_d_beta[cycleindex]; forecast_i = (L_i + T_i) * S_i[cycleindex]; - sum11 += weight[count - i] * d_forecast_d_alfa * d_forecast_d_alfa; - sum12 += weight[count - i] * d_forecast_d_alfa * d_forecast_d_beta; - sum22 += weight[count - i] * d_forecast_d_beta * d_forecast_d_beta; - sum13 += weight[count - i] * d_forecast_d_alfa * (actual - forecast_i); - sum23 += weight[count - i] * d_forecast_d_beta * (actual - forecast_i); + sum11 += smapeWeight(count - i) * d_forecast_d_alfa * d_forecast_d_alfa; + sum12 += smapeWeight(count - i) * d_forecast_d_alfa * d_forecast_d_beta; + sum22 += smapeWeight(count - i) * d_forecast_d_beta * d_forecast_d_beta; + sum13 += smapeWeight(count - i) * d_forecast_d_alfa * (actual - forecast_i); + sum23 += smapeWeight(count - i) * d_forecast_d_beta * (actual - forecast_i); if (i >= solver->getForecastSkip()) // Don't measure during the warmup period { double fcst = (L_i + T_i) * S_i[cycleindex]; - error += (fcst - actual) * (fcst - actual) * weight[count - i]; + error += (fcst - actual) * (fcst - actual) * smapeWeight(count - i); if (fabs(fcst + actual) > ROUNDING_ERROR) { error_smape += - fabs(fcst - actual) / fabs(fcst + actual) * weight[count - i]; - error_smape_weights += weight[count - i]; + fabs(fcst - actual) / fabs(fcst + actual) * smapeWeight(count - i); + error_smape_weights += smapeWeight(count - i); standarddeviation += (fcst - actual) * (fcst - actual); } } @@ -1402,8 +1402,8 @@ ForecastSolver::Metrics ForecastSolver::Croston::generateForecast( { if (fabs(f_i + history_i) > ROUNDING_ERROR) { error_smape += fabs(f_i - history_i) / fabs(f_i + history_i) * - weight[count - i]; - error_smape_weights += weight[count - i]; + smapeWeight(count - i); + error_smape_weights += smapeWeight(count - i); } } } diff --git a/test/forecast_11/forecast_11.xml b/test/forecast_11/forecast_11.xml new file mode 100644 index 0000000000..3abf16e696 --- /dev/null +++ b/test/forecast_11/forecast_11.xml @@ -0,0 +1,2640 @@ + + + Forecast long-history test (weight[] bounds) + + Regression scenario for the weight[] out-of-bounds read: a weekly + forecast with >500 history buckets forces the SMAPE weight index + (count - i) above MAXBUCKETS. Under an AddressSanitizer build the + pre-fix binary reports a global-buffer-overflow on weight; the + smapeWeight() clamp makes it clean. No golden .expect on purpose: + the test passes iff frepple processes the model without error. + + 2022-12-26T00:00:00 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2013-01-07T00:00:00 + 100 + + + 2013-01-14T00:00:00 + 105 + + + 2013-01-21T00:00:00 + 110 + + + 2013-01-28T00:00:00 + 115 + + + 2013-02-04T00:00:00 + 120 + + + 2013-02-11T00:00:00 + 125 + + + 2013-02-18T00:00:00 + 130 + + + 2013-02-25T00:00:00 + 135 + + + 2013-03-04T00:00:00 + 140 + + + 2013-03-11T00:00:00 + 145 + + + 2013-03-18T00:00:00 + 150 + + + 2013-03-25T00:00:00 + 155 + + + 2013-04-01T00:00:00 + 160 + + + 2013-04-08T00:00:00 + 100 + + + 2013-04-15T00:00:00 + 105 + + + 2013-04-22T00:00:00 + 110 + + + 2013-04-29T00:00:00 + 115 + + + 2013-05-06T00:00:00 + 120 + + + 2013-05-13T00:00:00 + 125 + + + 2013-05-20T00:00:00 + 130 + + + 2013-05-27T00:00:00 + 135 + + + 2013-06-03T00:00:00 + 140 + + + 2013-06-10T00:00:00 + 145 + + + 2013-06-17T00:00:00 + 150 + + + 2013-06-24T00:00:00 + 155 + + + 2013-07-01T00:00:00 + 160 + + + 2013-07-08T00:00:00 + 100 + + + 2013-07-15T00:00:00 + 105 + + + 2013-07-22T00:00:00 + 110 + + + 2013-07-29T00:00:00 + 115 + + + 2013-08-05T00:00:00 + 120 + + + 2013-08-12T00:00:00 + 125 + + + 2013-08-19T00:00:00 + 130 + + + 2013-08-26T00:00:00 + 135 + + + 2013-09-02T00:00:00 + 140 + + + 2013-09-09T00:00:00 + 145 + + + 2013-09-16T00:00:00 + 150 + + + 2013-09-23T00:00:00 + 155 + + + 2013-09-30T00:00:00 + 160 + + + 2013-10-07T00:00:00 + 100 + + + 2013-10-14T00:00:00 + 105 + + + 2013-10-21T00:00:00 + 110 + + + 2013-10-28T00:00:00 + 115 + + + 2013-11-04T00:00:00 + 120 + + + 2013-11-11T00:00:00 + 125 + + + 2013-11-18T00:00:00 + 130 + + + 2013-11-25T00:00:00 + 135 + + + 2013-12-02T00:00:00 + 140 + + + 2013-12-09T00:00:00 + 145 + + + 2013-12-16T00:00:00 + 150 + + + 2013-12-23T00:00:00 + 155 + + + 2013-12-30T00:00:00 + 160 + + + 2014-01-06T00:00:00 + 100 + + + 2014-01-13T00:00:00 + 105 + + + 2014-01-20T00:00:00 + 110 + + + 2014-01-27T00:00:00 + 115 + + + 2014-02-03T00:00:00 + 120 + + + 2014-02-10T00:00:00 + 125 + + + 2014-02-17T00:00:00 + 130 + + + 2014-02-24T00:00:00 + 135 + + + 2014-03-03T00:00:00 + 140 + + + 2014-03-10T00:00:00 + 145 + + + 2014-03-17T00:00:00 + 150 + + + 2014-03-24T00:00:00 + 155 + + + 2014-03-31T00:00:00 + 160 + + + 2014-04-07T00:00:00 + 100 + + + 2014-04-14T00:00:00 + 105 + + + 2014-04-21T00:00:00 + 110 + + + 2014-04-28T00:00:00 + 115 + + + 2014-05-05T00:00:00 + 120 + + + 2014-05-12T00:00:00 + 125 + + + 2014-05-19T00:00:00 + 130 + + + 2014-05-26T00:00:00 + 135 + + + 2014-06-02T00:00:00 + 140 + + + 2014-06-09T00:00:00 + 145 + + + 2014-06-16T00:00:00 + 150 + + + 2014-06-23T00:00:00 + 155 + + + 2014-06-30T00:00:00 + 160 + + + 2014-07-07T00:00:00 + 100 + + + 2014-07-14T00:00:00 + 105 + + + 2014-07-21T00:00:00 + 110 + + + 2014-07-28T00:00:00 + 115 + + + 2014-08-04T00:00:00 + 120 + + + 2014-08-11T00:00:00 + 125 + + + 2014-08-18T00:00:00 + 130 + + + 2014-08-25T00:00:00 + 135 + + + 2014-09-01T00:00:00 + 140 + + + 2014-09-08T00:00:00 + 145 + + + 2014-09-15T00:00:00 + 150 + + + 2014-09-22T00:00:00 + 155 + + + 2014-09-29T00:00:00 + 160 + + + 2014-10-06T00:00:00 + 100 + + + 2014-10-13T00:00:00 + 105 + + + 2014-10-20T00:00:00 + 110 + + + 2014-10-27T00:00:00 + 115 + + + 2014-11-03T00:00:00 + 120 + + + 2014-11-10T00:00:00 + 125 + + + 2014-11-17T00:00:00 + 130 + + + 2014-11-24T00:00:00 + 135 + + + 2014-12-01T00:00:00 + 140 + + + 2014-12-08T00:00:00 + 145 + + + 2014-12-15T00:00:00 + 150 + + + 2014-12-22T00:00:00 + 155 + + + 2014-12-29T00:00:00 + 160 + + + 2015-01-05T00:00:00 + 100 + + + 2015-01-12T00:00:00 + 105 + + + 2015-01-19T00:00:00 + 110 + + + 2015-01-26T00:00:00 + 115 + + + 2015-02-02T00:00:00 + 120 + + + 2015-02-09T00:00:00 + 125 + + + 2015-02-16T00:00:00 + 130 + + + 2015-02-23T00:00:00 + 135 + + + 2015-03-02T00:00:00 + 140 + + + 2015-03-09T00:00:00 + 145 + + + 2015-03-16T00:00:00 + 150 + + + 2015-03-23T00:00:00 + 155 + + + 2015-03-30T00:00:00 + 160 + + + 2015-04-06T00:00:00 + 100 + + + 2015-04-13T00:00:00 + 105 + + + 2015-04-20T00:00:00 + 110 + + + 2015-04-27T00:00:00 + 115 + + + 2015-05-04T00:00:00 + 120 + + + 2015-05-11T00:00:00 + 125 + + + 2015-05-18T00:00:00 + 130 + + + 2015-05-25T00:00:00 + 135 + + + 2015-06-01T00:00:00 + 140 + + + 2015-06-08T00:00:00 + 145 + + + 2015-06-15T00:00:00 + 150 + + + 2015-06-22T00:00:00 + 155 + + + 2015-06-29T00:00:00 + 160 + + + 2015-07-06T00:00:00 + 100 + + + 2015-07-13T00:00:00 + 105 + + + 2015-07-20T00:00:00 + 110 + + + 2015-07-27T00:00:00 + 115 + + + 2015-08-03T00:00:00 + 120 + + + 2015-08-10T00:00:00 + 125 + + + 2015-08-17T00:00:00 + 130 + + + 2015-08-24T00:00:00 + 135 + + + 2015-08-31T00:00:00 + 140 + + + 2015-09-07T00:00:00 + 145 + + + 2015-09-14T00:00:00 + 150 + + + 2015-09-21T00:00:00 + 155 + + + 2015-09-28T00:00:00 + 160 + + + 2015-10-05T00:00:00 + 100 + + + 2015-10-12T00:00:00 + 105 + + + 2015-10-19T00:00:00 + 110 + + + 2015-10-26T00:00:00 + 115 + + + 2015-11-02T00:00:00 + 120 + + + 2015-11-09T00:00:00 + 125 + + + 2015-11-16T00:00:00 + 130 + + + 2015-11-23T00:00:00 + 135 + + + 2015-11-30T00:00:00 + 140 + + + 2015-12-07T00:00:00 + 145 + + + 2015-12-14T00:00:00 + 150 + + + 2015-12-21T00:00:00 + 155 + + + 2015-12-28T00:00:00 + 160 + + + 2016-01-04T00:00:00 + 100 + + + 2016-01-11T00:00:00 + 105 + + + 2016-01-18T00:00:00 + 110 + + + 2016-01-25T00:00:00 + 115 + + + 2016-02-01T00:00:00 + 120 + + + 2016-02-08T00:00:00 + 125 + + + 2016-02-15T00:00:00 + 130 + + + 2016-02-22T00:00:00 + 135 + + + 2016-02-29T00:00:00 + 140 + + + 2016-03-07T00:00:00 + 145 + + + 2016-03-14T00:00:00 + 150 + + + 2016-03-21T00:00:00 + 155 + + + 2016-03-28T00:00:00 + 160 + + + 2016-04-04T00:00:00 + 100 + + + 2016-04-11T00:00:00 + 105 + + + 2016-04-18T00:00:00 + 110 + + + 2016-04-25T00:00:00 + 115 + + + 2016-05-02T00:00:00 + 120 + + + 2016-05-09T00:00:00 + 125 + + + 2016-05-16T00:00:00 + 130 + + + 2016-05-23T00:00:00 + 135 + + + 2016-05-30T00:00:00 + 140 + + + 2016-06-06T00:00:00 + 145 + + + 2016-06-13T00:00:00 + 150 + + + 2016-06-20T00:00:00 + 155 + + + 2016-06-27T00:00:00 + 160 + + + 2016-07-04T00:00:00 + 100 + + + 2016-07-11T00:00:00 + 105 + + + 2016-07-18T00:00:00 + 110 + + + 2016-07-25T00:00:00 + 115 + + + 2016-08-01T00:00:00 + 120 + + + 2016-08-08T00:00:00 + 125 + + + 2016-08-15T00:00:00 + 130 + + + 2016-08-22T00:00:00 + 135 + + + 2016-08-29T00:00:00 + 140 + + + 2016-09-05T00:00:00 + 145 + + + 2016-09-12T00:00:00 + 150 + + + 2016-09-19T00:00:00 + 155 + + + 2016-09-26T00:00:00 + 160 + + + 2016-10-03T00:00:00 + 100 + + + 2016-10-10T00:00:00 + 105 + + + 2016-10-17T00:00:00 + 110 + + + 2016-10-24T00:00:00 + 115 + + + 2016-10-31T00:00:00 + 120 + + + 2016-11-07T00:00:00 + 125 + + + 2016-11-14T00:00:00 + 130 + + + 2016-11-21T00:00:00 + 135 + + + 2016-11-28T00:00:00 + 140 + + + 2016-12-05T00:00:00 + 145 + + + 2016-12-12T00:00:00 + 150 + + + 2016-12-19T00:00:00 + 155 + + + 2016-12-26T00:00:00 + 160 + + + 2017-01-02T00:00:00 + 100 + + + 2017-01-09T00:00:00 + 105 + + + 2017-01-16T00:00:00 + 110 + + + 2017-01-23T00:00:00 + 115 + + + 2017-01-30T00:00:00 + 120 + + + 2017-02-06T00:00:00 + 125 + + + 2017-02-13T00:00:00 + 130 + + + 2017-02-20T00:00:00 + 135 + + + 2017-02-27T00:00:00 + 140 + + + 2017-03-06T00:00:00 + 145 + + + 2017-03-13T00:00:00 + 150 + + + 2017-03-20T00:00:00 + 155 + + + 2017-03-27T00:00:00 + 160 + + + 2017-04-03T00:00:00 + 100 + + + 2017-04-10T00:00:00 + 105 + + + 2017-04-17T00:00:00 + 110 + + + 2017-04-24T00:00:00 + 115 + + + 2017-05-01T00:00:00 + 120 + + + 2017-05-08T00:00:00 + 125 + + + 2017-05-15T00:00:00 + 130 + + + 2017-05-22T00:00:00 + 135 + + + 2017-05-29T00:00:00 + 140 + + + 2017-06-05T00:00:00 + 145 + + + 2017-06-12T00:00:00 + 150 + + + 2017-06-19T00:00:00 + 155 + + + 2017-06-26T00:00:00 + 160 + + + 2017-07-03T00:00:00 + 100 + + + 2017-07-10T00:00:00 + 105 + + + 2017-07-17T00:00:00 + 110 + + + 2017-07-24T00:00:00 + 115 + + + 2017-07-31T00:00:00 + 120 + + + 2017-08-07T00:00:00 + 125 + + + 2017-08-14T00:00:00 + 130 + + + 2017-08-21T00:00:00 + 135 + + + 2017-08-28T00:00:00 + 140 + + + 2017-09-04T00:00:00 + 145 + + + 2017-09-11T00:00:00 + 150 + + + 2017-09-18T00:00:00 + 155 + + + 2017-09-25T00:00:00 + 160 + + + 2017-10-02T00:00:00 + 100 + + + 2017-10-09T00:00:00 + 105 + + + 2017-10-16T00:00:00 + 110 + + + 2017-10-23T00:00:00 + 115 + + + 2017-10-30T00:00:00 + 120 + + + 2017-11-06T00:00:00 + 125 + + + 2017-11-13T00:00:00 + 130 + + + 2017-11-20T00:00:00 + 135 + + + 2017-11-27T00:00:00 + 140 + + + 2017-12-04T00:00:00 + 145 + + + 2017-12-11T00:00:00 + 150 + + + 2017-12-18T00:00:00 + 155 + + + 2017-12-25T00:00:00 + 160 + + + 2018-01-01T00:00:00 + 100 + + + 2018-01-08T00:00:00 + 105 + + + 2018-01-15T00:00:00 + 110 + + + 2018-01-22T00:00:00 + 115 + + + 2018-01-29T00:00:00 + 120 + + + 2018-02-05T00:00:00 + 125 + + + 2018-02-12T00:00:00 + 130 + + + 2018-02-19T00:00:00 + 135 + + + 2018-02-26T00:00:00 + 140 + + + 2018-03-05T00:00:00 + 145 + + + 2018-03-12T00:00:00 + 150 + + + 2018-03-19T00:00:00 + 155 + + + 2018-03-26T00:00:00 + 160 + + + 2018-04-02T00:00:00 + 100 + + + 2018-04-09T00:00:00 + 105 + + + 2018-04-16T00:00:00 + 110 + + + 2018-04-23T00:00:00 + 115 + + + 2018-04-30T00:00:00 + 120 + + + 2018-05-07T00:00:00 + 125 + + + 2018-05-14T00:00:00 + 130 + + + 2018-05-21T00:00:00 + 135 + + + 2018-05-28T00:00:00 + 140 + + + 2018-06-04T00:00:00 + 145 + + + 2018-06-11T00:00:00 + 150 + + + 2018-06-18T00:00:00 + 155 + + + 2018-06-25T00:00:00 + 160 + + + 2018-07-02T00:00:00 + 100 + + + 2018-07-09T00:00:00 + 105 + + + 2018-07-16T00:00:00 + 110 + + + 2018-07-23T00:00:00 + 115 + + + 2018-07-30T00:00:00 + 120 + + + 2018-08-06T00:00:00 + 125 + + + 2018-08-13T00:00:00 + 130 + + + 2018-08-20T00:00:00 + 135 + + + 2018-08-27T00:00:00 + 140 + + + 2018-09-03T00:00:00 + 145 + + + 2018-09-10T00:00:00 + 150 + + + 2018-09-17T00:00:00 + 155 + + + 2018-09-24T00:00:00 + 160 + + + 2018-10-01T00:00:00 + 100 + + + 2018-10-08T00:00:00 + 105 + + + 2018-10-15T00:00:00 + 110 + + + 2018-10-22T00:00:00 + 115 + + + 2018-10-29T00:00:00 + 120 + + + 2018-11-05T00:00:00 + 125 + + + 2018-11-12T00:00:00 + 130 + + + 2018-11-19T00:00:00 + 135 + + + 2018-11-26T00:00:00 + 140 + + + 2018-12-03T00:00:00 + 145 + + + 2018-12-10T00:00:00 + 150 + + + 2018-12-17T00:00:00 + 155 + + + 2018-12-24T00:00:00 + 160 + + + 2018-12-31T00:00:00 + 100 + + + 2019-01-07T00:00:00 + 105 + + + 2019-01-14T00:00:00 + 110 + + + 2019-01-21T00:00:00 + 115 + + + 2019-01-28T00:00:00 + 120 + + + 2019-02-04T00:00:00 + 125 + + + 2019-02-11T00:00:00 + 130 + + + 2019-02-18T00:00:00 + 135 + + + 2019-02-25T00:00:00 + 140 + + + 2019-03-04T00:00:00 + 145 + + + 2019-03-11T00:00:00 + 150 + + + 2019-03-18T00:00:00 + 155 + + + 2019-03-25T00:00:00 + 160 + + + 2019-04-01T00:00:00 + 100 + + + 2019-04-08T00:00:00 + 105 + + + 2019-04-15T00:00:00 + 110 + + + 2019-04-22T00:00:00 + 115 + + + 2019-04-29T00:00:00 + 120 + + + 2019-05-06T00:00:00 + 125 + + + 2019-05-13T00:00:00 + 130 + + + 2019-05-20T00:00:00 + 135 + + + 2019-05-27T00:00:00 + 140 + + + 2019-06-03T00:00:00 + 145 + + + 2019-06-10T00:00:00 + 150 + + + 2019-06-17T00:00:00 + 155 + + + 2019-06-24T00:00:00 + 160 + + + 2019-07-01T00:00:00 + 100 + + + 2019-07-08T00:00:00 + 105 + + + 2019-07-15T00:00:00 + 110 + + + 2019-07-22T00:00:00 + 115 + + + 2019-07-29T00:00:00 + 120 + + + 2019-08-05T00:00:00 + 125 + + + 2019-08-12T00:00:00 + 130 + + + 2019-08-19T00:00:00 + 135 + + + 2019-08-26T00:00:00 + 140 + + + 2019-09-02T00:00:00 + 145 + + + 2019-09-09T00:00:00 + 150 + + + 2019-09-16T00:00:00 + 155 + + + 2019-09-23T00:00:00 + 160 + + + 2019-09-30T00:00:00 + 100 + + + 2019-10-07T00:00:00 + 105 + + + 2019-10-14T00:00:00 + 110 + + + 2019-10-21T00:00:00 + 115 + + + 2019-10-28T00:00:00 + 120 + + + 2019-11-04T00:00:00 + 125 + + + 2019-11-11T00:00:00 + 130 + + + 2019-11-18T00:00:00 + 135 + + + 2019-11-25T00:00:00 + 140 + + + 2019-12-02T00:00:00 + 145 + + + 2019-12-09T00:00:00 + 150 + + + 2019-12-16T00:00:00 + 155 + + + 2019-12-23T00:00:00 + 160 + + + 2019-12-30T00:00:00 + 100 + + + 2020-01-06T00:00:00 + 105 + + + 2020-01-13T00:00:00 + 110 + + + 2020-01-20T00:00:00 + 115 + + + 2020-01-27T00:00:00 + 120 + + + 2020-02-03T00:00:00 + 125 + + + 2020-02-10T00:00:00 + 130 + + + 2020-02-17T00:00:00 + 135 + + + 2020-02-24T00:00:00 + 140 + + + 2020-03-02T00:00:00 + 145 + + + 2020-03-09T00:00:00 + 150 + + + 2020-03-16T00:00:00 + 155 + + + 2020-03-23T00:00:00 + 160 + + + 2020-03-30T00:00:00 + 100 + + + 2020-04-06T00:00:00 + 105 + + + 2020-04-13T00:00:00 + 110 + + + 2020-04-20T00:00:00 + 115 + + + 2020-04-27T00:00:00 + 120 + + + 2020-05-04T00:00:00 + 125 + + + 2020-05-11T00:00:00 + 130 + + + 2020-05-18T00:00:00 + 135 + + + 2020-05-25T00:00:00 + 140 + + + 2020-06-01T00:00:00 + 145 + + + 2020-06-08T00:00:00 + 150 + + + 2020-06-15T00:00:00 + 155 + + + 2020-06-22T00:00:00 + 160 + + + 2020-06-29T00:00:00 + 100 + + + 2020-07-06T00:00:00 + 105 + + + 2020-07-13T00:00:00 + 110 + + + 2020-07-20T00:00:00 + 115 + + + 2020-07-27T00:00:00 + 120 + + + 2020-08-03T00:00:00 + 125 + + + 2020-08-10T00:00:00 + 130 + + + 2020-08-17T00:00:00 + 135 + + + 2020-08-24T00:00:00 + 140 + + + 2020-08-31T00:00:00 + 145 + + + 2020-09-07T00:00:00 + 150 + + + 2020-09-14T00:00:00 + 155 + + + 2020-09-21T00:00:00 + 160 + + + 2020-09-28T00:00:00 + 100 + + + 2020-10-05T00:00:00 + 105 + + + 2020-10-12T00:00:00 + 110 + + + 2020-10-19T00:00:00 + 115 + + + 2020-10-26T00:00:00 + 120 + + + 2020-11-02T00:00:00 + 125 + + + 2020-11-09T00:00:00 + 130 + + + 2020-11-16T00:00:00 + 135 + + + 2020-11-23T00:00:00 + 140 + + + 2020-11-30T00:00:00 + 145 + + + 2020-12-07T00:00:00 + 150 + + + 2020-12-14T00:00:00 + 155 + + + 2020-12-21T00:00:00 + 160 + + + 2020-12-28T00:00:00 + 100 + + + 2021-01-04T00:00:00 + 105 + + + 2021-01-11T00:00:00 + 110 + + + 2021-01-18T00:00:00 + 115 + + + 2021-01-25T00:00:00 + 120 + + + 2021-02-01T00:00:00 + 125 + + + 2021-02-08T00:00:00 + 130 + + + 2021-02-15T00:00:00 + 135 + + + 2021-02-22T00:00:00 + 140 + + + 2021-03-01T00:00:00 + 145 + + + 2021-03-08T00:00:00 + 150 + + + 2021-03-15T00:00:00 + 155 + + + 2021-03-22T00:00:00 + 160 + + + 2021-03-29T00:00:00 + 100 + + + 2021-04-05T00:00:00 + 105 + + + 2021-04-12T00:00:00 + 110 + + + 2021-04-19T00:00:00 + 115 + + + 2021-04-26T00:00:00 + 120 + + + 2021-05-03T00:00:00 + 125 + + + 2021-05-10T00:00:00 + 130 + + + 2021-05-17T00:00:00 + 135 + + + 2021-05-24T00:00:00 + 140 + + + 2021-05-31T00:00:00 + 145 + + + 2021-06-07T00:00:00 + 150 + + + 2021-06-14T00:00:00 + 155 + + + 2021-06-21T00:00:00 + 160 + + + 2021-06-28T00:00:00 + 100 + + + 2021-07-05T00:00:00 + 105 + + + 2021-07-12T00:00:00 + 110 + + + 2021-07-19T00:00:00 + 115 + + + 2021-07-26T00:00:00 + 120 + + + 2021-08-02T00:00:00 + 125 + + + 2021-08-09T00:00:00 + 130 + + + 2021-08-16T00:00:00 + 135 + + + 2021-08-23T00:00:00 + 140 + + + 2021-08-30T00:00:00 + 145 + + + 2021-09-06T00:00:00 + 150 + + + 2021-09-13T00:00:00 + 155 + + + 2021-09-20T00:00:00 + 160 + + + 2021-09-27T00:00:00 + 100 + + + 2021-10-04T00:00:00 + 105 + + + 2021-10-11T00:00:00 + 110 + + + 2021-10-18T00:00:00 + 115 + + + 2021-10-25T00:00:00 + 120 + + + 2021-11-01T00:00:00 + 125 + + + 2021-11-08T00:00:00 + 130 + + + 2021-11-15T00:00:00 + 135 + + + 2021-11-22T00:00:00 + 140 + + + 2021-11-29T00:00:00 + 145 + + + 2021-12-06T00:00:00 + 150 + + + 2021-12-13T00:00:00 + 155 + + + 2021-12-20T00:00:00 + 160 + + + 2021-12-27T00:00:00 + 100 + + + 2022-01-03T00:00:00 + 105 + + + 2022-01-10T00:00:00 + 110 + + + 2022-01-17T00:00:00 + 115 + + + 2022-01-24T00:00:00 + 120 + + + 2022-01-31T00:00:00 + 125 + + + 2022-02-07T00:00:00 + 130 + + + 2022-02-14T00:00:00 + 135 + + + 2022-02-21T00:00:00 + 140 + + + 2022-02-28T00:00:00 + 145 + + + 2022-03-07T00:00:00 + 150 + + + 2022-03-14T00:00:00 + 155 + + + 2022-03-21T00:00:00 + 160 + + + 2022-03-28T00:00:00 + 100 + + + 2022-04-04T00:00:00 + 105 + + + 2022-04-11T00:00:00 + 110 + + + 2022-04-18T00:00:00 + 115 + + + 2022-04-25T00:00:00 + 120 + + + 2022-05-02T00:00:00 + 125 + + + 2022-05-09T00:00:00 + 130 + + + 2022-05-16T00:00:00 + 135 + + + 2022-05-23T00:00:00 + 140 + + + 2022-05-30T00:00:00 + 145 + + + 2022-06-06T00:00:00 + 150 + + + 2022-06-13T00:00:00 + 155 + + + 2022-06-20T00:00:00 + 160 + + + 2022-06-27T00:00:00 + 100 + + + 2022-07-04T00:00:00 + 105 + + + 2022-07-11T00:00:00 + 110 + + + 2022-07-18T00:00:00 + 115 + + + 2022-07-25T00:00:00 + 120 + + + 2022-08-01T00:00:00 + 125 + + + 2022-08-08T00:00:00 + 130 + + + 2022-08-15T00:00:00 + 135 + + + 2022-08-22T00:00:00 + 140 + + + 2022-08-29T00:00:00 + 145 + + + 2022-09-05T00:00:00 + 150 + + + 2022-09-12T00:00:00 + 155 + + + 2022-09-19T00:00:00 + 160 + + + 2022-09-26T00:00:00 + 100 + + + 2022-10-03T00:00:00 + 105 + + + 2022-10-10T00:00:00 + 110 + + + 2022-10-17T00:00:00 + 115 + + + 2022-10-24T00:00:00 + 120 + + + 2022-10-31T00:00:00 + 125 + + + 2022-11-07T00:00:00 + 130 + + + 2022-11-14T00:00:00 + 135 + + + 2022-11-21T00:00:00 + 140 + + + 2022-11-28T00:00:00 + 145 + + + 2022-12-05T00:00:00 + 150 + + + 2022-12-12T00:00:00 + 155 + + + 2022-12-19T00:00:00 + 160 + + + + + + +