Research Lab研究实验室 · Markets · Method note市场 · 方法说明
Rotation happens a level down轮动发生在更细的一层
In the year to 25 September 2026, the S&P 500’s Information Technology sector returned 33%. Inside it, semiconductors returned 57% and Software & Services lost 2%. A sector is an average of businesses that can move in opposite directions, and an eleven-row sector table — the kind most market dashboards show, ours included until now — stops exactly where the interesting part begins.
截至 2026 年 9 月 25 日的一年里,标普 500 的信息技术板块上涨 33%。拆开来看,半导体行业组涨了 57%,软件与服务却跌了 2%。板块只是若干门生意的平均数,而这些生意完全可能背道而驰;大多数行情面板只有一张 11 行的板块表——我们的也不例外,直到现在——恰好停在了最值得看的地方。
TL;DR要点
The S&P 500’s 11 GICS sectors split into 25 industry groups, and this year’s rotation happened at that level. Only 8 of S&P’s 36 official GICS index symbols carry any price history on Yahoo Finance, so we rebuilt all 25 groups from the index’s own members, cap-weighted, and checked them against those 8: one-day moves match to the hundredth of a point. The shortcut we refused on the way — pricing the past with today’s members — read the S&P 500’s year at +18.37% against an official +17.24%.
标普 500 的 11 个 GICS 板块之下共有 25 个行业组,今年的轮动正发生在这一层。在 Yahoo Finance 上,标普 36 个官方 GICS 指数代码中只有 8 个带有历史价格,于是我们用指数自己的成分股、按市值加权重建了全部 25 个行业组,再拿这 8 个官方指数核对:单日涨跌幅精确到 0.01 个百分点完全一致。途中我们拒绝了一条捷径——“用今天的成分股给过去定价”——它算出的标普 500 一年回报是 +18.37%,而官方数字是 +17.24%。
Why sector tables stop too early为什么板块表停得太早
Most sector views, including the two already on our Markets page, are ETF prices — the Select Sector SPDRs, one fund per sector. They answer “which sector?” and stop. Yet rotation usually happens a level down: semiconductors against software inside Information Technology, banks against insurers inside Financials. A sector fund averages the two halves, so the move is invisible by construction.
GICS, the classification S&P and MSCI use to file every listed company, splits the 11 sectors into 25 industry groups, and most of them have no ETF on the S&P 500’s own definition. Even the sector funds are not quite their sectors: the Select Sector SPDRs cap single names, and three companies are over half of S&P 500 IT.
S&P’s official indices would be the obvious source (^SP500-4530 is semiconductors). We measured them on Yahoo Finance: 35 of the 36 symbols resolve, but only 8 carry any history. The rest return today’s quote alone — not even a one-week return.
大多数板块视图——包括我们市场页上原有的两个——用的都是 ETF 价格:Select Sector SPDR 系列,每个板块一只基金。它们回答“哪个板块”,然后就止步了。可轮动通常发生在更细的一层:信息技术内部是半导体对软件,金融内部是银行对保险。板块基金把两半平均在一起,这种分化在结构上就看不到。
GICS(全球行业分类标准)是标普与 MSCI 给每家上市公司归类的体系,它把 11 个板块细分为 25 个行业组,而其中大多数都没有按标普 500 自身口径跟踪的 ETF。就连板块基金也不完全等于板块本身:Select Sector SPDR 对单一个股设有权重上限,而标普 500 信息技术板块一半以上的权重集中在三家公司身上。
最直接的数据源本应是标普的官方指数(半导体的代码是 ^SP500-4530)。我们在 Yahoo Finance 上实测过:36 个代码中有 35 个能查到,但只有 8 个带有历史数据,其余只返回当天的报价——连一周的回报都算不出来。
Rebuilding 25 indices from 503 companies用 503 家公司重建 25 个指数
Each group is rebuilt as a cap-weighted index, in which a company counts in proportion to its market value. The inputs are public: weights from the daily holdings of SPY, an ETF that replicates the index; each company’s GICS sub-industry and the date it joined, from Wikipedia’s list of S&P 500 companies; and daily adjusted closes (prices restated for splits and dividends) for all 503 names.
Each member’s weight on the snapshot date becomes a fixed share count — weight divided by that day’s adjusted close — so a group’s value on any day is the sum of shares times price. That is buy-and-hold with constant shares, which is what a cap-weighted index is between rebalances.
Three things that had to be right
Each is pinned by a test that fails without it.
- Each window counts only companies already in the index when it began. The usual shortcut prices today’s members back through time, which builds in survivorship bias — judging the past by the companies still here. Companies join the S&P 500 after they have risen, so today’s list imports their pre-entry gains into the index’s past.
- Share counts are struck against the same adjusted series the returns come from. Adjusted prices are rewritten after every split, dividend and spin-off; pairing a raw price with an adjusted one would misweight every company that has split since, by exactly the split ratio. Spin-offs are covered too: DD→Q, FDX→FDXF and HON→HONA show no cliff.
- Year-to-date starts from last year’s final close, not January’s first, which would throw away 2 January’s move. A figure computed mid-session drops today’s unfinished bar rather than mixing a live quote into a column of closes.
Checked against the official indices
The 8 official indices with history, plus the S&P 500 itself, are an independent answer key. On price-only closes, to match them, one-day moves reproduce to the hundredth — Semiconductors +0.48% against +0.48%, Banks +1.30% against +1.30%, the S&P 500 +0.51% against +0.51% — and one week to three months land within about 0.1 percentage points for every group of ten or more names.
每个行业组都按市值加权指数(公司按市值大小计入)的方式重建。输入都是公开数据:权重来自 SPY(一只完全复制标普 500 的 ETF)每日公布的持仓;每家公司的 GICS 子行业及纳入指数的日期,来自维基百科的标普 500 成分股列表;以及全部 503 只成分股的每日复权收盘价(按拆股和分红调整后的价格)。
每只成分股在快照日的权重被折算成固定的“股数”——权重除以当天的复权收盘价——于是某个行业组在任意一天的市值,就是各成员股数乘以当天价格之和。这相当于股数不变的买入并持有,而这正是市值加权指数在两次调整之间的样子。
必须做对的三件事
每一条都有测试锁定,去掉它,测试就会失败。
- 每个区间只计入区间开始时已经在指数里的公司。常见的捷径是拿今天的成分股一路往回算,这就自带了幸存者偏差——用今天还留在场上的公司去评判过去。公司往往是大涨之后才被纳入标普 500 的,于是今天的名单把它们入选前的涨幅也带进了指数的过去。
- 股数用与回报同一条复权价格序列来折算。每次拆股、分红和分拆之后,复权价格都会被整体改写;若把未复权价格与复权价格混用,所有在快照之后拆过股的公司都会被错配权重,误差恰好等于拆股比例。分拆同样覆盖在内:DD→Q、FDX→FDXF、HON→HONA 都没有出现断崖。
- 年初至今从去年最后一个收盘价算起,而不是 1 月的第一个——那样会把 1 月 2 日当天的涨跌整个丢掉。盘中计算时则舍弃当天尚未收盘的那根 K 线,不把实时报价混进一列收盘价里。
与官方指数核对
有历史数据的 8 个官方指数,加上标普 500 本身,构成一份独立的“标准答案”。为与之匹配,核对时使用不含股息的价格数据:单日涨跌幅精确到 0.01 个百分点完全一致——半导体 +0.48% 对 +0.48%,银行 +1.30% 对 +1.30%,标普 500 +0.51% 对 +0.51%;从 1 周到 3 个月,凡成分股在十家及以上的行业组,误差都在约 0.1 个百分点以内。
What we found我们发现了什么
One sector, three directions一个板块,三个方向
Year to the 25 September 2026 close, total return. The sector figure is not wrong; it averages a group up 57% with a group down 2%, and shows neither.
截至 2026 年 9 月 25 日收盘的一年,总回报。板块数字本身没有错,只是它把一个涨了 57% 的行业组和一个跌了 2% 的行业组平均在了一起,结果两者都看不见。
Did it matter? The weight view这对指数重要吗?看权重
A return alone does not say whether a move mattered: +20% on a group that is 1% of the index is a fifth of a point. So the panel also shows each group’s change in index weight, in percentage points (pp). IT gained 4.2pp over the year, and its three groups sum to it:
单看涨跌幅,说明不了一次上涨对指数有多重要:一个只占指数 1% 的行业组涨 20%,也只相当于指数的五分之一个百分点。所以面板还给出每个行业组的指数权重变化,单位是百分点。这一年里信息技术板块的指数权重上升了 4.2 个百分点,正好是其下三个行业组之和:
| Industry group行业组 | Return涨跌幅 | Index weight change (pp)指数权重变化(百分点) |
|---|---|---|
| Information Technology (sector)信息技术(板块) | +33% | +4.2 |
| Semiconductors & Semiconductor Equipment半导体与半导体设备 | +57% | +4.50 |
| Technology Hardware & Equipment技术硬件与设备 | +43% | +1.84 |
| Software & Services软件与服务 | −2% | −2.13 |
Survivorship, measured幸存者偏差,实测
The same year, three ways — price-only, to match the official indices:
同一年用三种方法计算——为与官方指数一致,均为不含股息的价格回报:
| Today’s members, backcast今天的成分股回溯 | Counted from add date按纳入日期计入 | Official index官方指数 | |
|---|---|---|---|
| S&P 500标普 500 | +18.37% | +17.31% | +17.24% |
| Semiconductors & Semiconductor Equipment半导体与半导体设备 | +58.0% | +56.6% | +55.8% |
Dating each company’s entry closes most of the gap, without touching the arithmetic.
按纳入日期计入每家公司之后,缺口基本被补上,而计算公式本身一处都没改。
The rotation map行业组轮动象限图
Below the table, a map plots each group’s return against the S&P 500 over a longer window (across) and a shorter one (up), bubble area its index weight. Ahead of the index on both windows is leading, behind on both lagging; ahead on the longer only is weakening, on the shorter only improving. On the 25 September 2026 close, at one month against three, Technology Hardware, Software & Services and Media & Entertainment led (30% of the index), Semiconductors and Autos were improving (20%), and sixteen of the 25 groups lagged — together, 32% of the index.
表格下方的象限图,横轴是每个行业组在较长区间内相对标普 500 的超额回报,纵轴是较短区间内的,气泡面积代表指数权重。两个区间都跑赢指数为「领先」,都跑输为「落后」;只在长区间跑赢为「转弱」,只在短区间跑赢为「改善」。以 2026 年 9 月 25 日收盘、1 个月对 3 个月来看:技术硬件与设备、软件与服务、媒体与娱乐处于领先(合计占指数 30%),半导体和汽车两个行业组处于改善(20%),25 个行业组中有 16 个处于落后——合计占指数的 32%。
Two bugs it found in our own pages它揪出了我们自己页面上的两个错误
The panel also exposed that the two older sector sections beside it each had their own idea of where a period starts, and both were wrong without looking it. Both turned up while the panel was being built, and were fixed on 26 September 2026:
面板还暴露出,同页两个旧板块模块对“一个区间从哪里开始”各有各的算法,而且都错了,却看不出任何异常。两处都是在搭建面板时发现的,并于 2026 年 9 月 26 日修复:
| Where位置 | Shown显示值 | Correct正确值 |
|---|---|---|
| Rotation ranking — Health Care “YTD”轮动排名——医疗保健「年初至今」 | +28.1% | +11.6% |
| Rotation ranking — XLK “YTD”轮动排名——XLK「年初至今」 | +41.5% | +36.8% |
| Rotation grid — Energy YTD轮动表——能源 年初至今 | +38.6% | +41.5% |
| Rotation grid — Industrials YTD轮动表——工业 年初至今 | +8.7% | +10.8% |
- The ranking’s “YTD” was a one-year return: it divided by the first weekly close in a year of data, so XLK’s “YTD” was exactly its one-year figure. The Health Care and XLK rows were measured on 25 September 2026.
- The grid dropped every window’s first session, starting at the first close inside the window, so year-to-date lost all of 2 January and disagreed with the panel beside it.
One rule, in one place
All three sections now call one rule: a period’s base is the last close on or before its anniversary — the close before the window, not the first one inside it — and year-to-date’s anniversary is 31 December. A series too short to reach it reports nothing rather than a shorter period’s return under a longer heading, which is exactly how “YTD” had become one year. Three rules fixed in place would agree today and drift the next time one was edited.
- 排名表里的「年初至今」其实是一年回报:它除以的是一年数据里的第一个周收盘价,所以 XLK 的「年初至今」恰好等于它的一年回报。医疗保健和 XLK 两行数字测于 2026 年 9 月 25 日。
- 轮动表丢掉了每个区间的第一个交易日:它从区间内的第一个收盘价起算,于是年初至今丢掉了 1 月 2 日一整天的涨跌,和旁边的面板说法不一。
一条规则,只写在一处
现在三个模块调用同一条规则:一个区间的基准,是其周年日当天或之前的最后一个收盘价——区间开始之前的那个收盘价,而不是区间内的第一个;年初至今的周年日是上一年的 12 月 31 日。数据太短、够不到周年日的序列直接不报数,而不是把较短区间的回报挂在较长区间的标题下——「年初至今」当初就是这样变成了一年回报。三条规则各自就地修补,今天一致,下次谁一改就会各自漂移。
What it still gets wrong它仍然不完美的地方
- Removed members are missing from history. Date-gating handles companies that joined, not those that left, so long horizons drift: Media & Entertainment’s one-year figure is 1.5pp under the official index.
- Small groups can miss by more than a point. Telecommunication Services is four names, and EchoStar alone accounts for its gap — so every row shows its constituent count.
- Share counts are held at the latest snapshot’s. Buybacks and float changes move them a few percent a year at most.
- Ours are total returns, and uncapped. A high-yield sector reads above S&P’s price-only headline index by its dividend, and our IT row can disagree with the capped XLK with neither broken.
- The map’s windows overlap — the longer contains the shorter — so its axes are not independent. We did not chain-link them apart: each window counts its own membership, and the quotient would mix two.
- A quadrant describes where relative returns have been, not where they are going. Nothing here recommends buying or selling any group.
- 已被剔除的成分股不在历史里。按纳入日期过滤解决的是“后来加入”的公司,补不回“中途离开”的公司,所以区间越长越会漂移:媒体与娱乐的一年回报比官方指数低 1.5 个百分点。
- 小行业组的误差可能超过 1 个百分点。电信服务只有四家公司,它与官方指数的差距完全来自 EchoStar 一家——所以页面上每一行都标明了成分股数量。
- 股数沿用最新快照的数值。回购和流通股变化一年最多影响几个百分点。
- 我们用的是总回报,且不设个股上限。高股息板块会比只算价格的标普主流指数高出其间的股息;我们的信息技术板块也可能与设有上限的 XLK 不一致,但两者都没有错。
- 象限图的两个区间是重叠的——较长区间包含较短区间——所以两条坐标轴并不独立。我们没有用链式拆分把两者分开:每个区间只计入自己起点时的成分股,相除会把两套成分混在一起。
- 象限描述的是相对回报过去所处的位置,而不是未来的方向。本文不构成买入或卖出任何行业组的建议。
Check it yourself亲自验证
On the Markets page, under Sector Rotation, the table “GICS Sectors & Industry Groups — S&P 500” opens each sector into its groups and switches between Return, vs S&P 500 and Weight change. The rotation map below it offers four window pairs — 1W/1M, 1M/3M (the default), 1M/6M and 3M/1Y — and trails each bubble back through its last five weekly closes. Every coordinate is a cell from the table’s vs S&P 500 view, so any bubble can be checked against its row. The data is today’s, not 25 September’s.
What pins it: tests/test_gics.py (57 tests, 12 of them on the arithmetic, on prices small enough to check by hand), tests/test_periods.py (12, including a year that ends on a weekend), a 109-check script for the table and map, and a separate comparison against the official indices, run on live market data.
在市场页的「板块轮动」下方,名为「GICS 行业表现 — 标普500一级行业与行业组」的表格可以把每个板块展开为行业组,并在「涨跌幅」「相对标普500」「权重变化」三种视图间切换。表格下方的轮动象限图提供四组区间搭配——1 周/1 月、1 月/3 月(默认)、1 月/6 月、3 月/1 年——每个气泡身后拖着一条轨迹,回溯它过去五个周收盘时的位置。每个坐标都是表格「相对标普500」视图里的一格,任何一个气泡都可以回到它那一行去核对。页面上是最新数据,而不是 9 月 25 日的数据。
测试锁定:tests/test_gics.py(57 个测试,其中 12 个针对计算本身,用的是足以手算核对的价格)、tests/test_periods.py(12 个,包括一年恰好在周末结束的情形)、一个 109 项检查的表格与象限图脚本,以及一个单独的、需用实时行情数据运行的官方指数比对脚本。
Sources: the GICS panel (bae8c9d), the shared period rule and the fixes it made (8bd8fed), the rotation map (b54023e) and its trails (6c5928f), all dated 26 September 2026; the method notes in ystocker/gics.py and ystocker/periods.py.
资料来源:GICS 面板(bae8c9d)、统一的区间规则及其修复(8bd8fed)、轮动象限图(b54023e)及其轨迹(6c5928f),均为 2026 年 9 月 26 日;方法说明见 ystocker/gics.py 与 ystocker/periods.py。