timeprice 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +52 -0
  3. data/DATA_LICENSES.md +16 -1
  4. data/README.md +29 -5
  5. data/data/cpi/eu.json +406 -403
  6. data/data/cpi/jp.json +78 -75
  7. data/data/cpi/uk.json +513 -510
  8. data/data/cpi/us.json +488 -485
  9. data/data/cpi/vn.json +342 -339
  10. data/data/fx/usd/1999.json +23 -7
  11. data/data/fx/usd/2000.json +23 -7
  12. data/data/fx/usd/2001.json +23 -7
  13. data/data/fx/usd/2002.json +23 -7
  14. data/data/fx/usd/2003.json +23 -7
  15. data/data/fx/usd/2004.json +23 -7
  16. data/data/fx/usd/2005.json +23 -7
  17. data/data/fx/usd/2006.json +23 -7
  18. data/data/fx/usd/2007.json +23 -7
  19. data/data/fx/usd/2008.json +23 -7
  20. data/data/fx/usd/2009.json +23 -7
  21. data/data/fx/usd/2010.json +23 -7
  22. data/data/fx/usd/2011.json +23 -7
  23. data/data/fx/usd/2012.json +23 -7
  24. data/data/fx/usd/2013.json +23 -7
  25. data/data/fx/usd/2014.json +23 -7
  26. data/data/fx/usd/2015.json +23 -7
  27. data/data/fx/usd/2016.json +23 -7
  28. data/data/fx/usd/2017.json +23 -7
  29. data/data/fx/usd/2018.json +23 -7
  30. data/data/fx/usd/2019.json +23 -7
  31. data/data/fx/usd/2020.json +23 -7
  32. data/data/fx/usd/2021.json +23 -7
  33. data/data/fx/usd/2022.json +23 -7
  34. data/data/fx/usd/2023.json +23 -7
  35. data/data/fx/usd/2024.json +23 -7
  36. data/data/fx/usd/2025.json +24 -5
  37. data/data/fx/usd/2026.json +24 -5
  38. data/data/fx/usd/_annual.json +145 -0
  39. data/data/manifest.json +90 -0
  40. data/lib/timeprice/cli.rb +3 -3
  41. data/lib/timeprice/compare.rb +1 -1
  42. data/lib/timeprice/cpi_lookup.rb +64 -18
  43. data/lib/timeprice/data_loader.rb +47 -8
  44. data/lib/timeprice/errors.rb +4 -4
  45. data/lib/timeprice/exchange.rb +8 -8
  46. data/lib/timeprice/granularity.rb +41 -10
  47. data/lib/timeprice/inflation.rb +5 -5
  48. data/lib/timeprice/sources/coverage.rb +27 -32
  49. data/lib/timeprice/supported.rb +39 -22
  50. data/lib/timeprice/version.rb +1 -1
  51. data/lib/timeprice.rb +2 -2
  52. metadata +3 -15
  53. data/data/fx/usd/1983.json +0 -11
  54. data/data/fx/usd/1986.json +0 -11
  55. data/data/fx/usd/1987.json +0 -11
  56. data/data/fx/usd/1988.json +0 -11
  57. data/data/fx/usd/1989.json +0 -11
  58. data/data/fx/usd/1990.json +0 -11
  59. data/data/fx/usd/1991.json +0 -11
  60. data/data/fx/usd/1992.json +0 -11
  61. data/data/fx/usd/1993.json +0 -11
  62. data/data/fx/usd/1994.json +0 -11
  63. data/data/fx/usd/1995.json +0 -11
  64. data/data/fx/usd/1996.json +0 -11
  65. data/data/fx/usd/1997.json +0 -11
  66. data/data/fx/usd/1998.json +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a91644504f73e6324d522d189233539a5515ca51cf0be58b1a34da90ff78220d
4
- data.tar.gz: f6120dc38bb433e1dc8ac56e523b3c547d9323b578f34a27bddee3e43b48c9a2
3
+ metadata.gz: 5f350843e8e12653e2f798d8f9afec193001e911e0f36910d0473724f33d79f8
4
+ data.tar.gz: 3d1107eb101dd95ec6c2203fe6f1843f9249cf5046cf838577094c67a0fe63c0
5
5
  SHA512:
6
- metadata.gz: b8b0f99a9962bad944a02499761a586e860d50a3707e70de4d1549c6bf624ea5bf1a9d1d2beae488abdfc6646d825320259a196bfac177e64c25edab90e721e5
7
- data.tar.gz: 54bb2545e7c9f9bbdb202994f3d5f53bb020a36bde0a2d8627c734a1c0e4312fcbe0237ce2b23409af9253ddc809ae74129dec43b17b94c559bcefa8917142cf
6
+ metadata.gz: a7efbb6d151b4fd4c9c6d4697fc9c755c9a0d2e6b8e1e32d828a1416737dbfbd00d9143c64edde191eaea3f7f758b96ac1d4b93c9f765fbc5d0993bf68b0be7a
7
+ data.tar.gz: 3a5b598b62cf93b992ed4ba5d069f84475c91a0be636600451fb3247caaa5c494c44b39268ed5e6107c34f923606521d42374d3300de42ad5a7449f53ae37e39
data/CHANGELOG.md CHANGED
@@ -5,6 +5,58 @@ Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [0.6.0] - 2026-05-12
9
+
10
+ ### Added
11
+ - **Five new countries: AU, CA, KR, CN, RU.** CPI + FX coverage:
12
+ - AU (Australia): quarterly CPI from ABS 6401.0, annual baseline from World
13
+ Bank `FP.CPI.TOTL`; AUD daily FX from Frankfurter.
14
+ - CA (Canada): monthly CPI from Statistics Canada WDS (table 18-10-0004-01),
15
+ annual baseline from World Bank; CAD daily FX from Frankfurter.
16
+ - KR (Korea, Rep.): monthly CPI from IMF Data Portal CPI dataflow, annual
17
+ baseline from World Bank; KRW daily FX from Frankfurter. (KOSIS Open API
18
+ is a future upgrade path — see `scripts/sources/kosis.rb`.)
19
+ - CN (China): annual CPI from World Bank, monthly layered from IMF Data
20
+ Portal; CNY daily FX from Frankfurter.
21
+ - RU (Russia): annual CPI from World Bank, monthly layered from IMF; RUB FX
22
+ from IMF IFS `ENDA_XDC_USD_RATE` written as annual averages to
23
+ `_annual.json` (Frankfurter dropped RUB after the ECB suspended reference
24
+ rates in March 2022, so daily RUB is intentionally not bundled).
25
+ - `KRW` added to `Supported::ZERO_DECIMAL_CURRENCIES`.
26
+
27
+ ### Changed
28
+ - **Schema v3 → v4.** Backward-compatible bump:
29
+ - CPI files gain an optional `series.quarterly` block (keyed `YYYY-Qn`)
30
+ alongside `series.monthly` and `series.annual`. Files without quarterly
31
+ data are byte-identical to v3 layout other than the version field.
32
+ - `DataLoader` accepts both v3 and v4 files; new writes are v4.
33
+ - `Granularity` gains `:quarterly`, `:annual_from_quarterly_avg`,
34
+ `:quarterly_from_annual_fallback`, and `:monthly_from_quarterly_fallback`.
35
+ `CpiLookup` resolves "YYYY-Qn" keys and falls back monthly → quarterly →
36
+ annual.
37
+
38
+ ## [0.5.0] - 2026-05-11
39
+
40
+ ### Changed
41
+ - **Schema v2 → v3.** Breaking change to the bundled data contract. v0.4.x
42
+ data files will not load on v0.5.0.
43
+ - New top-level `data/manifest.json` — single source of truth for which
44
+ countries and currencies the bundle supports. `Supported.countries` /
45
+ `Supported.currencies` derive from it at runtime; the hardcoded Ruby
46
+ constants `Supported::COUNTRIES` / `CURRENCIES` are gone. Custom callers
47
+ that referenced those constants must switch to the method form.
48
+ - CPI files use nested `series: { monthly, annual }` and a structured
49
+ `index: { base_period, rebased_at }` block in place of the freeform
50
+ `base_year` string. Top-level `source` and `updated_at` removed —
51
+ `providers[]` is the source of truth for provenance.
52
+ - FX year files now carry `provenance` + `providers` blocks, symmetric
53
+ with CPI.
54
+ - All annual FX (today only VND from World Bank) lives in
55
+ `data/fx/usd/_annual.json` — the single canonical source, every year.
56
+ Per-year files (`data/fx/usd/<year>.json`) hold daily rates only. Pre-1999
57
+ stub year files are gone. `Exchange.lookup_usd_base` collapses to a
58
+ two-tier chain (daily → annual fallback), one source per tier.
59
+
8
60
  ## [0.4.0] - 2026-05-11
9
61
 
10
62
  ### Changed
data/DATA_LICENSES.md CHANGED
@@ -14,8 +14,15 @@ string.
14
14
  | World Bank | `FP.CPI.TOTL` (JP CPI fallback) | Creative Commons Attribution 4.0 International (CC BY 4.0) | https://datacatalog.worldbank.org/public-licenses#cc-by | Source: World Bank, FP.CPI.TOTL |
15
15
  | World Bank | `FP.CPI.TOTL` (VN CPI, annual fallback) | Creative Commons Attribution 4.0 International (CC BY 4.0) | https://datacatalog.worldbank.org/public-licenses#cc-by | Source: World Bank, FP.CPI.TOTL |
16
16
  | International Monetary Fund | CPI dataflow `VNM.CPI._T.IX.M` via IMF Data Portal (VN CPI, monthly primary) | Free reuse with attribution per IMF terms | https://www.imf.org/external/terms.htm | Source: IMF Data Portal CPI dataflow |
17
- | European Central Bank (via Frankfurter) | Daily reference rates, USD base, EUR/GBP/JPY | ECB reference rates — free reuse; Frankfurter is a non-commercial republisher with no separate license | https://www.ecb.europa.eu/services/disclaimer/html/index.en.html | FX data: European Central Bank reference rates via Frankfurter |
17
+ | European Central Bank (via Frankfurter) | Daily reference rates, USD base, EUR/GBP/JPY/AUD/CAD/KRW/CNY | ECB reference rates — free reuse; Frankfurter is a non-commercial republisher with no separate license | https://www.ecb.europa.eu/services/disclaimer/html/index.en.html | FX data: European Central Bank reference rates via Frankfurter |
18
18
  | World Bank | `PA.NUS.FCRF` (VND annual average FX, broadcast daily) | Creative Commons Attribution 4.0 International (CC BY 4.0) | https://datacatalog.worldbank.org/public-licenses#cc-by | VND FX: World Bank, PA.NUS.FCRF |
19
+ | Australian Bureau of Statistics | `CPI` dataflow, key `3.10001.10.50.Q` (AU CPI, quarterly, all groups, weighted average of eight capital cities) | Creative Commons Attribution 4.0 International (CC BY 4.0) | https://www.abs.gov.au/website-privacy-copyright-and-disclaimer/copyright-and-creative-commons | Source: Australian Bureau of Statistics, 6401.0 Consumer Price Index |
20
+ | Statistics Canada | Table 18-10-0004-01, vector `v41690973` (CA CPI, monthly, all-items, not seasonally adjusted) | Statistics Canada Open License | https://www.statcan.gc.ca/en/reference/licence | Source: Statistics Canada, table 18-10-0004-01 |
21
+ | International Monetary Fund | CPI dataflow `KOR.CPI._T.IX.M` (KR CPI, monthly) | Free reuse with attribution per IMF terms | https://www.imf.org/external/terms.htm | Source: IMF Data Portal CPI dataflow |
22
+ | International Monetary Fund | CPI dataflow `CHN.CPI._T.IX.M` (CN CPI, monthly) | Free reuse with attribution per IMF terms | https://www.imf.org/external/terms.htm | Source: IMF Data Portal CPI dataflow |
23
+ | International Monetary Fund | CPI dataflow `RUS.CPI._T.IX.M` (RU CPI, monthly) | Free reuse with attribution per IMF terms | https://www.imf.org/external/terms.htm | Source: IMF Data Portal CPI dataflow |
24
+ | International Monetary Fund | IFS dataflow `M.RUS.ENDA_XDC_USD_RATE` (RUB/USD, period-average, annual mean written to `_annual.json`) | Free reuse with attribution per IMF terms | https://www.imf.org/external/terms.htm | Source: IMF International Financial Statistics |
25
+ | World Bank | `FP.CPI.TOTL` (AU/CA/KR/CN/RU CPI annual baselines) | Creative Commons Attribution 4.0 International (CC BY 4.0) | https://datacatalog.worldbank.org/public-licenses#cc-by | Source: World Bank, FP.CPI.TOTL |
19
26
 
20
27
  ## Notes
21
28
 
@@ -25,6 +32,14 @@ string.
25
32
  - The Vietnam VND FX series is the **annual average** broadcast to every day in
26
33
  the year — it is intentionally not a daily market rate. Do not use it for
27
34
  intraday or trade-execution purposes.
35
+ - **RUB FX is annual-only** (from IMF IFS period averages). Frankfurter (ECB)
36
+ stopped publishing RUB daily reference rates in March 2022 after the ECB
37
+ suspended the rate, and no other free, no-API-key daily source covers the
38
+ full series. Daily RUB lookups fall back to the annual average and the
39
+ result is tagged so consumers can detect the degradation.
40
+ - **AU CPI is published quarterly only.** Lookups against "YYYY-MM" keys for
41
+ Australia fall back to the quarter that contains the month, and the result
42
+ is tagged `:monthly_from_quarterly_fallback`.
28
43
  - Eurostat HICP is harmonized across the Eurozone and is **not** the same as
29
44
  any national CPI. We use it for the `EU` country code; national CPIs are out
30
45
  of scope for v0.1.
data/README.md CHANGED
@@ -99,10 +99,19 @@ Coverage is derived from the bundled `data/` files. Re-check with `timeprice sou
99
99
  | Eurozone (EA) | EUR | Eurostat HICP (`prc_hicp_midx`) | Monthly + annual | 1996-01 → present |
100
100
  | Japan | JPY | World Bank `FP.CPI.TOTL` (fallback) | Annual | 1960 → 2024 |
101
101
  | Vietnam | VND | IMF Data Portal CPI dataflow (monthly primary) + World Bank `FP.CPI.TOTL` (annual fallback) | Monthly + annual | 1995 → present |
102
-
103
- **FX (USD base):** ECB reference rates via Frankfurter for **EUR / GBP / JPY**, daily
104
- 1999 present. **VND** uses the World Bank annual average (`PA.NUS.FCRF`) broadcast to
105
- every day in the year, from 1983 → present.
102
+ | Australia | AUD | ABS 6401.0 (quarterly) + World Bank `FP.CPI.TOTL` (annual baseline) | Quarterly + annual | 1948-Q3 → present |
103
+ | Canada | CAD | Statistics Canada WDS (table 18-10-0004-01, vector `v41690973`) + World Bank annual baseline | Monthly + annual | 1914-01 → present |
104
+ | Korea (Rep.) | KRW | IMF Data Portal CPI dataflow + World Bank annual baseline | Monthly + annual | 1990-01 → present |
105
+ | China | CNY | World Bank `FP.CPI.TOTL` (annual primary) + IMF Data Portal CPI dataflow (monthly layer) | Monthly + annual | 1990-01 → present |
106
+ | Russia | RUB | World Bank `FP.CPI.TOTL` (annual primary) + IMF Data Portal CPI dataflow (monthly layer) | Monthly + annual | 1992-01 → present |
107
+
108
+ **FX (USD base):** ECB reference rates via Frankfurter for **EUR / GBP / JPY / AUD /
109
+ CAD / KRW / CNY**, daily 1999 → present. **VND** uses the World Bank annual average
110
+ (`PA.NUS.FCRF`), one value per year, from 1983 → present. **RUB** uses IMF IFS
111
+ period-average rates as annual means (`ENDA_XDC_USD_RATE`) — Frankfurter dropped RUB
112
+ after the ECB suspended its reference rate in March 2022, so daily RUB is intentionally
113
+ not bundled. Annual-fallback results (VND, RUB) are tagged `granularity: :annual` so
114
+ callers know they did not get a daily rate.
106
115
 
107
116
  Triangulated cross-rates (e.g. GBP → JPY) go through USD on the same effective date.
108
117
  Weekend/holiday dates fall back up to 7 days to the nearest prior trading day.
@@ -222,7 +231,7 @@ namespace :inflation do
222
231
  desc "Print 1990→today inflation for the supported countries"
223
232
  task :report do
224
233
  today = Date.today.strftime("%Y-%m")
225
- %w[US UK EU JP VN].each do |c|
234
+ %w[US UK EU JP VN AU CA KR CN RU].each do |c|
226
235
  r = Timeprice.inflation(amount: 100, from: "1990", to: today, country: c)
227
236
  puts "#{c}: 100 in 1990 → #{r.amount.round(2)} in #{today} (#{r.granularity})"
228
237
  end
@@ -265,6 +274,21 @@ license — see `DATA_LICENSES.md` and `NOTICE` for the full table and license U
265
274
  If you redistribute results derived from this gem, reproduce the relevant attribution
266
275
  strings. `timeprice sources` prints them in plain text and as JSON.
267
276
 
277
+ ## Data format
278
+
279
+ Bundled data lives under `data/` in schema v3 and is self-describing:
280
+
281
+ - `data/manifest.json` — the supported set (countries, currencies, FX years).
282
+ - `data/cpi/<country>.json` — CPI for one country: `series.{monthly,annual}`,
283
+ structured `index` block, `provenance` ranges, `providers` attribution.
284
+ - `data/fx/usd/<year>.json` — daily USD-base FX rates for one year (one file
285
+ per year, EUR/GBP/JPY).
286
+ - `data/fx/usd/_annual.json` — annual USD-base FX rates across all years for
287
+ currencies sourced at annual resolution (today only VND). Used as the
288
+ fallback tier when no daily rate covers the requested date.
289
+
290
+ `scripts/check_schema_stability.rb` enforces the shape in CI.
291
+
268
292
  ## Author
269
293
 
270
294
  Built by [Patrick](https://github.com/patrick204nqh).