Module: Timeprice::Forecast::CpiForecaster Private
- Defined in:
- lib/timeprice/forecast/cpi_forecaster.rb
Overview
This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.
Project a country’s CPI index forward from the last bundled data point.
Constant Summary collapse
- DEFAULT_WINDOW_YEARS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
10- HORIZON_CAP_YEARS =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
5
Class Method Summary collapse
- .build_result(last_key:, last_value:, target:, horizon_months:, window_years:, stats:, warnings:) ⇒ Object private
- .build_warnings(series, last_key, window_years, horizon_months) ⇒ Object private
- .last_entry(series) ⇒ Object private
- .load_series(country) ⇒ Object private
- .months_between(from_key, to_key) ⇒ Object private
-
.pick_series(data) ⇒ Object
private
Prefer monthly when present; fall back to annual.
- .project(country:, target:, window_years: DEFAULT_WINDOW_YEARS) ⇒ Forecast::Result private
Class Method Details
.build_result(last_key:, last_value:, target:, horizon_months:, window_years:, stats:, warnings:) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/timeprice/forecast/cpi_forecaster.rb', line 70 def build_result(last_key:, last_value:, target:, horizon_months:, window_years:, stats:, warnings:) years_forward = horizon_months / 12.0 value = last_value * ((1.0 + stats[:cagr])**years_forward) low = last_value * ((1.0 + stats[:cagr] - stats[:sigma_yoy])**years_forward) high = last_value * ((1.0 + stats[:cagr] + stats[:sigma_yoy])**years_forward) Forecast::Result.new( value: value, low: low, high: high, projection_method: "cagr_trailing", window_years: window_years, sigma_pct: stats[:sigma_yoy], last_known_date: last_key, target_date: target, horizon_months: horizon_months, basis_kind: :cpi, warnings: warnings.uniq ) end |
.build_warnings(series, last_key, window_years, horizon_months) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
62 63 64 65 66 67 68 |
# File 'lib/timeprice/forecast/cpi_forecaster.rb', line 62 def build_warnings(series, last_key, window_years, horizon_months) warnings = [] earliest = series.keys.map { |k| Cagr.parse(k).year }.min warnings << "insufficient_window" if Cagr.parse(last_key).year - window_years < earliest warnings << "horizon_exceeds_cap" if horizon_months > HORIZON_CAP_YEARS * 12 warnings.uniq end |
.last_entry(series) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
57 58 59 60 |
# File 'lib/timeprice/forecast/cpi_forecaster.rb', line 57 def last_entry(series) last_key = series.keys.max_by { |k| Cagr.parse(k) } [last_key, series[last_key].to_f] end |
.load_series(country) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
49 50 51 52 53 54 55 |
# File 'lib/timeprice/forecast/cpi_forecaster.rb', line 49 def load_series(country) data = DataLoader.load_cpi(country.to_s.upcase) series = pick_series(data) fail DataNotFound, "no CPI series for #{country}" if series.empty? series end |
.months_between(from_key, to_key) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
43 44 45 46 47 |
# File 'lib/timeprice/forecast/cpi_forecaster.rb', line 43 def months_between(from_key, to_key) f = Cagr.parse(from_key) t = Cagr.parse(to_key) ((t.year - f.year) * 12) + (t.month - f.month) end |
.pick_series(data) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Prefer monthly when present; fall back to annual.
36 37 38 39 40 41 |
# File 'lib/timeprice/forecast/cpi_forecaster.rb', line 36 def pick_series(data) monthly = data.dig("series", "monthly") || {} return monthly unless monthly.empty? data.dig("series", "annual") || {} end |
.project(country:, target:, window_years: DEFAULT_WINDOW_YEARS) ⇒ Forecast::Result
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
24 25 26 27 28 29 30 31 32 33 |
# File 'lib/timeprice/forecast/cpi_forecaster.rb', line 24 def project(country:, target:, window_years: DEFAULT_WINDOW_YEARS) series = load_series(country) last_key, last_value = last_entry(series) horizon_months = months_between(last_key, target) warnings = build_warnings(series, last_key, window_years, horizon_months) stats = Cagr.compute(series: series, last_date: last_key, window_years: window_years) build_result(last_key: last_key, last_value: last_value, target: target, horizon_months: horizon_months, window_years: window_years, stats: stats, warnings: warnings) end |