Module: Timeprice::Compare::Series Private
- Defined in:
- lib/timeprice/compare/series.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.
Annual sample points for the result-card chart. Composes the same FX leg as run and a year-by-year measured-or-forecast CPI ratio for the destination country.
Each point is ‘{ date: “YYYY-01”, amount:, measured: }`. Forecast points additionally carry `:low` and `:high` for the ±1σ band.
Constant Summary collapse
- DEFAULT_AMOUNT =
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.
100.0
Class Method Summary collapse
- .build_context(from:, to:, amount:, forecast:) ⇒ Object private
- .coerce_points(from, to) ⇒ Object private
- .for(from:, to:, forecast: false, amount: DEFAULT_AMOUNT) ⇒ Object private
- .forecast_point(y:, last_year:, last_cpi:, source_in_dest:, source_cpi:, stats:) ⇒ Object private
- .forecast_stats(data, last_key, forecast, to_point, last_year) ⇒ Object private
- .last_known(data) ⇒ Object private
- .measured_point(y:, lookup:, source_in_dest:, source_cpi:) ⇒ Object private
- .point_for(year, ctx) ⇒ Object private
- .source_amount_in_dest(amount, from_point, to_point) ⇒ Object private
Class Method Details
.build_context(from:, to:, amount:, forecast:) ⇒ 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.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/timeprice/compare/series.rb', line 32 def build_context(from:, to:, amount:, forecast:) from_point, to_point, to_country = coerce_points(from, to) data = DataLoader.load_cpi(to_country) last_key, last_cpi = last_known(data) last_year = Forecast::Cagr.parse(last_key).year { source_in_dest: source_amount_in_dest(amount, from_point, to_point), source_cpi: CpiLookup.new(data).at(from_point.date.to_s).value.to_f, lookup: CpiLookup.new(data), last_year: last_year, last_cpi: last_cpi, from_year: Forecast::Cagr.parse(from_point.date.to_s).year, to_year: Forecast::Cagr.parse(to_point.date.to_s).year, stats: forecast_stats(data, last_key, forecast, to_point, last_year), } end |
.coerce_points(from, to) ⇒ 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.
50 51 52 53 54 55 56 57 |
# File 'lib/timeprice/compare/series.rb', line 50 def coerce_points(from, to) from_point = Point.coerce(from) to_point = Point.coerce(to) to_country = Supported.country_for_currency(to_point.currency) fail UnsupportedCurrency, to_point.currency unless to_country [from_point, to_point, to_country] end |
.for(from:, to:, forecast: false, amount: DEFAULT_AMOUNT) ⇒ 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.
27 28 29 30 |
# File 'lib/timeprice/compare/series.rb', line 27 def for(from:, to:, forecast: false, amount: DEFAULT_AMOUNT) ctx = build_context(from: from, to: to, amount: amount, forecast: forecast) (ctx[:from_year]..ctx[:to_year]).map { |y| point_for(y, ctx) } end |
.forecast_point(y:, last_year:, last_cpi:, source_in_dest:, source_cpi:, stats:) ⇒ 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.
100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/timeprice/compare/series.rb', line 100 def forecast_point(y:, last_year:, last_cpi:, source_in_dest:, source_cpi:, stats:) yrs = y - last_year mid = last_cpi * ((1.0 + stats[:cagr])**yrs) low = last_cpi * ((1.0 + stats[:cagr] - stats[:sigma_yoy])**yrs) high = last_cpi * ((1.0 + stats[:cagr] + stats[:sigma_yoy])**yrs) { date: "#{y}-01", amount: source_in_dest * (mid / source_cpi), low: source_in_dest * (low / source_cpi), high: source_in_dest * (high / source_cpi), measured: false, } end |
.forecast_stats(data, last_key, forecast, to_point, last_year) ⇒ 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.
72 73 74 75 76 77 78 79 80 |
# File 'lib/timeprice/compare/series.rb', line 72 def forecast_stats(data, last_key, forecast, to_point, last_year) return nil unless forecast && Forecast::Cagr.parse(to_point.date.to_s).year > last_year Forecast::Cagr.compute( series: Forecast::CpiForecaster.pick_series(data), last_date: last_key, window_years: Forecast::CpiForecaster::DEFAULT_WINDOW_YEARS ) end |
.last_known(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.
66 67 68 69 70 |
# File 'lib/timeprice/compare/series.rb', line 66 def last_known(data) annual_or_monthly = Forecast::CpiForecaster.pick_series(data) last_key = annual_or_monthly.keys.max_by { |k| Forecast::Cagr.parse(k) } [last_key, annual_or_monthly[last_key].to_f] end |
.measured_point(y:, lookup:, source_in_dest:, source_cpi:) ⇒ 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.
93 94 95 96 97 98 |
# File 'lib/timeprice/compare/series.rb', line 93 def measured_point(y:, lookup:, source_in_dest:, source_cpi:) cpi_y = lookup.at(y.to_s).value.to_f { date: "#{y}-01", amount: source_in_dest * (cpi_y / source_cpi), measured: true } rescue DataNotFound nil end |
.point_for(year, ctx) ⇒ 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.
82 83 84 85 86 87 88 89 90 91 |
# File 'lib/timeprice/compare/series.rb', line 82 def point_for(year, ctx) if year <= ctx[:last_year] measured_point(y: year, lookup: ctx[:lookup], source_in_dest: ctx[:source_in_dest], source_cpi: ctx[:source_cpi]) else forecast_point(y: year, last_year: ctx[:last_year], last_cpi: ctx[:last_cpi], source_in_dest: ctx[:source_in_dest], source_cpi: ctx[:source_cpi], stats: ctx[:stats]) end end |
.source_amount_in_dest(amount, from_point, to_point) ⇒ 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.
59 60 61 62 63 64 |
# File 'lib/timeprice/compare/series.rb', line 59 def source_amount_in_dest(amount, from_point, to_point) Exchange.convert( amount: amount, from: from_point.currency, to: to_point.currency, date: from_point.fx_anchor_date ).amount end |