Data format

The AHR999 data format

The dataset ships in two serializations — ahr999.json and ahr999.csv — with identical rows and columns. This page is the field-by-field contract: types, null handling, and the invariants you can build on.

JSON

Published at /datasets/ahr999.json. A single JSON array, one object per UTC calendar day, ordered oldest to newest. Pretty-printed with a two-space indent and a trailing newline so the git diff on each daily commit stays readable.

[
  {
    "date": "2017-08-17",
    "close": 4285.08,
    "ma200": null,
    "ahr999": null,
    "quantile5y": null,
    "windowKind": "insufficient_samples"
  },
  {
    "date": "2026-04-19",
    "close": 73801.79,
    "ma200": 86578.65964999999,
    "ahr999": 0.4116636687277032,
    "quantile5y": 0.13917808219178082,
    "windowKind": "rolling_5y"
  }
]

CSV

Published at /datasets/ahr999.csv. Same rows and columns as the JSON, RFC 4180 compatible, UTF-8, trailing newline. A JSON null is serialized as an empty field.

date,close,ma200,ahr999,quantile5y,windowKind
2017-08-17,4285.08,,,,insufficient_samples
...
2026-04-19,73801.79,86578.65964999999,0.4116636687277032,0.13917808219178082,rolling_5y

Field reference

FieldTypeNullableDescription
datestringnoUTC calendar day; the close is Binance's 00:00-to-24:00-UTC daily kline close.
closenumbernoUSDT per BTC, from klines?symbol=BTCUSDT&interval=1d, field [4].
ma200number | nullyes200-day simple moving average of close; null for the first 199 rows.
ahr999number | nullyes(close / ma200) × (close / fitted); null when ma200 is null.
quantile5ynumber | null, in [0, 1]yesEmpirical rank of ahr999 within the active window; null during the first 365 valid AHR observations.
windowKind"insufficient_samples" | "expanding" | "rolling_5y"noWhich window applied for this row.

Invariants you can rely on

  • Rows are sorted strictly ascending by date, with no duplicates.
  • No future dates: the latest date is always ≤ (today UTC − 1 day).
  • If ma200 === null, then ahr999 and quantile5y are null and windowKind === "insufficient_samples".
  • If ahr999 !== null and quantile5y === null, then windowKind === "insufficient_samples" — a valid AHR exists, but fewer than 365 observations to rank it.
  • quantile5y is a discrete rank: only values of the form k / N with N = validObservations ≤ 1825.
  • Once windowKind flips to "rolling_5y" (at the 1,825th valid AHR observation), it never flips back.
  • During normal incremental sync, close for a date more than 5 days old is stable; within the last 5 days it may be refined by Binance late corrections (a 5-day self-heal lookback).

Row counts

The dataset starts at 2017-08-17, so on any given day you should expect approximately:

rows ≈ (today_UTC − 2017-08-17) / 1 day

For reference, the 2026-04-19 snapshot has 3,168 rows. To consume the data programmatically, see the API reference; for how each value is derived, see the methodology.