{
  "url": "https://www.moonstonehq.com/articles/pokemon-card-index-construction",
  "slug": "pokemon-card-index-construction",
  "title": "Four Ways to Index the Same Pokemon Cards",
  "summary": "One basket of 27,810 cards, four standard index constructions, four answers from -1.99% to +7.72%. The weighting decides the number more than the market does.",
  "section": "Methodology",
  "published": "2026-09-22",
  "readMinutes": 10,
  "publisher": "moonstone",
  "findings": [
    {
      "value": "9.72",
      "measures": "index points of spread",
      "basis": "27,810 identical constituents, 23 days"
    },
    {
      "value": "+13.33%",
      "measures": "printed by a chain-linked index",
      "basis": "on a market forced to go exactly nowhere"
    },
    {
      "value": "23.24",
      "measures": "points moved by removing one card",
      "basis": "of 1,484, from a bad one-day print"
    },
    {
      "value": "18.67%",
      "measures": "of constituents never moved a cent",
      "basis": "5,191 of 27,810, across all 24 days"
    }
  ],
  "tables": [
    {
      "title": "Four indices over identical constituents, n = 27,810, 2026-08-30 = 100",
      "columns": [
        "Date",
        "Price-weighted",
        "Equal-weight",
        "Median card",
        "Chain-linked equal-weight"
      ],
      "rows": [
        {
          "Date": "2026-08-30",
          "Price-weighted": "100.00",
          "Equal-weight": "100.00",
          "Median card": "100.00",
          "Chain-linked equal-weight": "100.00"
        },
        {
          "Date": "2026-09-02",
          "Price-weighted": "100.12",
          "Equal-weight": "101.11",
          "Median card": "100.00",
          "Chain-linked equal-weight": "101.14"
        },
        {
          "Date": "2026-09-05",
          "Price-weighted": "100.58",
          "Equal-weight": "101.88",
          "Median card": "100.00",
          "Chain-linked equal-weight": "103.36"
        },
        {
          "Date": "2026-09-08",
          "Price-weighted": "97.01",
          "Equal-weight": "102.31",
          "Median card": "100.00",
          "Chain-linked equal-weight": "104.52"
        },
        {
          "Date": "2026-09-11",
          "Price-weighted": "97.57",
          "Equal-weight": "103.10",
          "Median card": "100.00",
          "Chain-linked equal-weight": "105.61"
        },
        {
          "Date": "2026-09-14",
          "Price-weighted": "97.56",
          "Equal-weight": "103.67",
          "Median card": "100.00",
          "Chain-linked equal-weight": "106.39"
        },
        {
          "Date": "2026-09-17",
          "Price-weighted": "96.97",
          "Equal-weight": "104.14",
          "Median card": "100.00",
          "Chain-linked equal-weight": "107.15"
        },
        {
          "Date": "2026-09-20",
          "Price-weighted": "97.88",
          "Equal-weight": "104.17",
          "Median card": "100.00",
          "Chain-linked equal-weight": "107.35"
        },
        {
          "Date": "2026-09-22",
          "Price-weighted": "98.01",
          "Equal-weight": "104.37",
          "Median card": "100.00",
          "Chain-linked equal-weight": "107.72"
        },
        {
          "Date": "Total change",
          "Price-weighted": "-1.99%",
          "Equal-weight": "+4.37%",
          "Median card": "0.00%",
          "Chain-linked equal-weight": "+7.72%"
        }
      ]
    },
    {
      "title": "The same three constructions rebuilt under price floors, 2026-08-30 to 2026-09-22",
      "columns": [
        "Floor at the first day",
        "Cards",
        "Equal-weight",
        "Price-weighted",
        "Median card"
      ],
      "rows": [
        {
          "Floor at the first day": "no floor",
          "Cards": "27,810",
          "Equal-weight": "+4.37%",
          "Price-weighted": "-1.99%",
          "Median card": "0.00%"
        },
        {
          "Floor at the first day": "$0.25 and up",
          "Cards": "22,198",
          "Equal-weight": "+3.71%",
          "Price-weighted": "-2.00%",
          "Median card": "0.00%"
        },
        {
          "Floor at the first day": "$1 and up",
          "Cards": "16,951",
          "Equal-weight": "+1.23%",
          "Price-weighted": "-2.05%",
          "Median card": "0.00%"
        },
        {
          "Floor at the first day": "$5 and up",
          "Cards": "12,761",
          "Equal-weight": "+0.57%",
          "Price-weighted": "-2.13%",
          "Median card": "0.00%"
        },
        {
          "Floor at the first day": "$25 and up",
          "Cards": "4,957",
          "Equal-weight": "-0.13%",
          "Price-weighted": "-2.50%",
          "Median card": "0.00%"
        },
        {
          "Floor at the first day": "$100 and up",
          "Cards": "1,484",
          "Equal-weight": "-1.34%",
          "Price-weighted": "-3.45%",
          "Median card": "0.00%"
        },
        {
          "Floor at the first day": "$500 and up",
          "Cards": "168",
          "Equal-weight": "-3.93%",
          "Price-weighted": "-7.34%",
          "Median card": "0.00%"
        }
      ]
    },
    {
      "title": "Buy-and-hold equal weight against chain-linked daily means, same cards, by price band",
      "columns": [
        "Slice",
        "Cards",
        "Buy and hold",
        "Chain-linked",
        "Gap"
      ],
      "rows": [
        {
          "Slice": "all",
          "Cards": "27,810",
          "Buy and hold": "+4.37%",
          "Chain-linked": "+7.72%",
          "Gap": "3.35 points"
        },
        {
          "Slice": "under $0.25",
          "Cards": "5,612",
          "Buy and hold": "+6.97%",
          "Chain-linked": "+13.60%",
          "Gap": "6.63 points"
        },
        {
          "Slice": "$0.25 to $1",
          "Cards": "5,247",
          "Buy and hold": "+11.72%",
          "Chain-linked": "+14.75%",
          "Gap": "3.03 points"
        },
        {
          "Slice": "$1 to $5",
          "Cards": "4,190",
          "Buy and hold": "+3.25%",
          "Chain-linked": "+4.08%",
          "Gap": "0.83 points"
        },
        {
          "Slice": "$5 to $25",
          "Cards": "7,804",
          "Buy and hold": "+1.01%",
          "Chain-linked": "+0.94%",
          "Gap": "-0.07 points"
        },
        {
          "Slice": "$25 to $100",
          "Cards": "3,473",
          "Buy and hold": "+0.39%",
          "Chain-linked": "+0.55%",
          "Gap": "0.15 points"
        },
        {
          "Slice": "$100 and up",
          "Cards": "1,484",
          "Buy and hold": "-1.34%",
          "Chain-linked": "+22.87%",
          "Gap": "24.21 points"
        },
        {
          "Slice": "placebo: every card forced flat",
          "Cards": "27,810",
          "Buy and hold": "0.00%",
          "Chain-linked": "+13.33%",
          "Gap": "13.33 points"
        }
      ]
    },
    {
      "title": "The seven sets whose 30-day change the guard now withholds, of 87 quoted on the landing tape, 2026-09-22",
      "columns": [
        "Set",
        "Change as published",
        "Change with the step neutralised",
        "Step date",
        "Constituents either side"
      ],
      "rows": [
        {
          "Set": "[Jungle](/set/jungle)",
          "Change as published": "-61.2%",
          "Change with the step neutralised": "-0.1%",
          "Step date": "2026-09-07",
          "Constituents either side": "64 and 64"
        },
        {
          "Set": "[Gym Heroes](/set/gym%20heroes)",
          "Change as published": "-54.7%",
          "Change with the step neutralised": "+2.0%",
          "Step date": "2026-09-07",
          "Constituents either side": "132 and 132"
        },
        {
          "Set": "[Gym Challenge](/set/gym%20challenge)",
          "Change as published": "-47.6%",
          "Change with the step neutralised": "+0.6%",
          "Step date": "2026-09-07",
          "Constituents either side": "138 and 138"
        },
        {
          "Set": "[Neo Destiny](/set/neo%20destiny)",
          "Change as published": "-49.4%",
          "Change with the step neutralised": "+1.4%",
          "Step date": "2026-09-07",
          "Constituents either side": "113 and 113"
        },
        {
          "Set": "[Team Rocket](/set/team%20rocket)",
          "Change as published": "-47.5%",
          "Change with the step neutralised": "+1.7%",
          "Step date": "2026-09-07",
          "Constituents either side": "83 and 83"
        },
        {
          "Set": "[Legendary Collection](/set/legendary%20collection)",
          "Change as published": "+27.5%",
          "Change with the step neutralised": "+0.3%",
          "Step date": "2026-09-11",
          "Constituents either side": "110 and 110"
        },
        {
          "Set": "[Aquapolis](/set/aquapolis)",
          "Change as published": "+2.7%",
          "Change with the step neutralised": "-15.6%",
          "Step date": "2026-09-07",
          "Constituents either side": "185 and 185"
        }
      ]
    }
  ],
  "charts": [],
  "sections": [
    "Same cards, same days, four honest constructions",
    "A chain-linked index prints +13.33% on a market that went exactly nowhere",
    "A composition change is not a price move, and our own code has had to learn it more than once",
    "Most constituents are not contributing information at all"
  ],
  "method": [
    "As of 2026-09-22. The balanced panel is every TCGplayer product in `price_history` carrying a price on ALL 24 days from day 20695 to day 20718 inclusive and joining a `cards` row on `tcg_id`: n = 27,810, against 43,800 priced on the two endpoints and 44,711 on the tape at all. Every panel is keyed on the TCGplayer product id and carries exactly one row per product. 51,719 catalogue rows carry a TCGplayer product id, and they resolve to 50,507 distinct ids: 1,212 ids are claimed by two rows each, 2,424 rows in all. Those pairs are not a Japanese print against its English twin, which is what we assumed before counting them. Every one of the 1,212 is a same-language pair, 972 Japanese and 240 English, and they are overwhelmingly one product indexed under two catalogue spellings of the same set, as the XY trainer kits are. Each id collapses to a single row, preferring an English row and then the lexically first catalogue id, so no product enters a cross-section, a factor sort or a census twice. The tie-break is stated rather than assumed away, because it decides which of the two spellings a shared product is filed under. Restricting to the balanced panel is what makes the comparison valid, since any difference between the four levels is then weighting and nothing else. Prices are flagship-printing TCGplayer market prices, which are ASKS. Price-weighted level at t is the sum of constituent prices at t, rebased so that day 20695 equals 100. Equal-weight level at t is the arithmetic mean over constituents of price at t divided by price at day 20695, rebased the same way. Median level uses the median of those same ratios, upper-middle on even samples. Chain-linked equal-weight compounds, day by day, one plus the cross-sectional arithmetic mean of that day's simple returns. The time-shuffle placebo permutes each card's sequence of daily gross returns with a fixed seed, leaving its 24-day outcome unchanged; the zero-drift placebo additionally overwrites each card's final price with its own opening price, so the correct index reading is exactly zero by construction. Leave-one-out influence recomputes the chain-linked level of the $100-and-up band with each constituent removed in turn, 1,484 recomputations. Entry and exit counts compare membership on day 20695 against day 20718 across the full 44,711-card tape. Days 20704 to 20713 are partial catalogue dumps; cards missing on any of them are excluded from the balanced panel by construction, which is why the panel is 27,810 rather than 43,800, and that exclusion is itself a selection that we state rather than hide: the balanced panel skews toward cards the dump reaches every day. The account of moonstone's own index constructions is read from source, not inferred: `src/server/market-index.ts` and `src/server/db/indices.ts` for the Pokemon Index and the species indices, `packages/core/src/ppt.ts` (`buildSetHistory`) for the set series, and `packages/core/src/pricing.ts` (`basketChangeOverDays`) for the guard. The set-index audit in the table above was run against the 87 sets quoted on the landing tape on 2026-09-22, which is the same universe the tape itself builds: every owned `sethist2:` series in the tape's set list, cut at the set's recorded release date, whose latest reading is $25 or more. A set is listed when the guard withholds its 30-day change; the neutralised column rescales the series from the largest single-reading step onward and re-reads the same window. The constituent column counts the priced cards in that set in `price_history` on the day before and the day of the step, which is a second source rather than a restatement of the first: on six of the seven sets that count's dollar sum equals the stored series level to the cent on both days, and on the seventh, Gym Challenge, the two differ by exactly $44.49 on both days, so one card sits in the provider's basket that our set-name join does not reach. A constant difference either side of a step is itself proof that no constituent entered or left across it. 30th Celebration is excluded from the table because it was released on 2026-09-16 and carries four days of post-release tape, so the 30-day window its flagged figure claims does not exist; it is withheld by the release-date rule, not by the guard, which is why the guard's count is 7 and the flagged count is 8. The guard withholds a change rather than adjusting it, so figures published after 2026-09-22 show fewer set moves, not different ones. Its constituent-count branch is live in code but inert on today's data: `buildSetHistory` emits a count on every point it writes from now on, and zero of the 61,681 points across the 200 stored series carries one, so every suppression on this tape came from the 20% step ceiling."
  ],
  "terms": "Figures are moonstone's own recorded measurements, dated as published. Quote them with the population stated beside them. The article at `url` is the human form of this file."
}