How to Detect Stock Splits in Historical Data
Detect stock splits in historical data from XBRL ratio tags and share-count cliffs: the corroboration logic behind StockFit's split API.

During StockFit's development we set out to build a historical record of stock splits straight from SEC filings, the same question every split calendar site answers (what split happened, and when), but for the question a backtest actually needs answered: how do you detect a split from the underlying data itself, reliably, for a company that never sends a press release? That is when we ran into the discrepancies. SEC EDGAR tags stock splits in XBRL, but simply reading the required concept turns out not to be enough, for a specific, well-documented reason, and naive detection strategies (watch for a big overnight price jump, trust the ratio tag's sign) both fail on real filings. This is the detection logic behind StockFit's /api/company/stock-splits family, built from roughly 2,500 tagged companies, and the specific ways it had to get corrected before the numbers could be trusted.
Why naive stock split detection fails
The obvious first approach is to watch daily closing prices for a large overnight drop or jump and infer a split from the ratio. It fails for two reasons. First, plenty of overnight price moves that look like a 2-for-1 split are just a bad earnings print or a sector selloff, so a price-only detector needs a second signal to avoid false positives. Second, and more fundamental, a price time series alone cannot tell you which of two exact numbers a split most affects: share count and per-share metrics like EPS. If your data source has already silently split-adjusted historical prices (many do), the split is invisible in price data entirely, but it is still there, unadjusted, in every share count and per-share XBRL fact filed before the event.
The structured evidence lives in the filings themselves, not in price history. That means SEC XBRL, and specifically, the two concepts issuers use to tag a split's conversion ratio.
Where split evidence lives in SEC filings
US GAAP defines us-gaap:StockholdersEquityNoteStockSplitConversionRatio1 (and its pre-2015 predecessor, us-gaap:StockholdersEquityNoteStockSplitConversionRatio) for exactly this: a company that executes a stock split tags the conversion ratio as a footnote fact in its next 10-K or 10-Q. Most filers tag it as a plain, dimensionless value. Some tag it only on the class_of_stock dimension, alongside their per-share-class facts, which means it never reaches a naive fact scan at all, only a dimensional-facts table built specifically to catch it.
// A cleanly-tagged forward split (NVIDIA, 10-for-1, June 2024)
{ "concept": "us-gaap:StockholdersEquityNoteStockSplitConversionRatio1", "value": 10, "period_end": "2024-06-30" }
// A split tagged only on the class-of-stock dimension — invisible to a plain facts scan
{ "concept": "us-gaap:StockholdersEquityNoteStockSplitConversionRatio1",
"axis": "us-gaap:StatementClassOfStockAxis", "member": "hnst:ClassACommonStockMember", "value": 2 }Reading that tag looks like the whole job. It is not. The tag tells you a split happened and roughly how big it was. It does not reliably tell you which direction.
The XBRL ratio tag direction problem
A forward split and a reverse split can be tagged with the exact same magnitude. A 2-for-1 forward split and a 1-for-2 reverse split are both, in some filer's hands, a value of 2, because the concept's definition does not enforce a sign convention and issuers, their outside counsel, and their XBRL tagging vendors do not all interpret "conversion ratio" the same way. vTv Therapeutics is the clearest case in our data: its own 8-K confirms a single 1-for-40 reverse split approved for both Class A and Class B common stock on the same day in November 2023, yet its FY2023 10-K tags that one event two different ways in the very same filing, 0.025 for Class A (the correct post-split ratio) and 40 (the untouched pre-split magnitude) for Class B, as shown in SEC's own rendered financial report for the filing. The Honest Company tagged its 2021 split both ways across different filings in its filing history. A scan that simply reads whichever tagged context it lands on first ships a wrong-direction split roughly as often as a filer contradicts itself, and a wrong-direction split does not just misdate an event, it inverts every share count and per-share figure computed on either side of it.
The fix is not a better parser. It is a second, independent signal that can confirm or override the tag: what actually happened to the company's reported share count around that date.
Corroborating a split with the share-count cliff
Every company also tags its outstanding share count, in us-gaap:CommonStockSharesOutstanding and dei:EntityCommonStockSharesOutstanding facts, filed quarterly regardless of whether a split happened. Bracket a candidate split date with the nearest share-count observation before and after it, and a real split shows up as a clean, discrete jump, the share-count cliff, close in magnitude to the tagged ratio. A wrongly-tagged direction shows up as a mismatch: the tag says 40 but the actual share count fell by roughly 40x, not rose.
The cliff is not treated symmetrically, because the two directions carry different amounts of ambiguity:
- Shares fell by roughly the tagged magnitude. This is unambiguous. A share count cannot collapse tenfold except through a reverse split, so a corroborated drop overrides the tag's stated direction and stores the reverse ratio. This is exactly what resolves vTv's contradictory Class B tag of
40to0.025, the value its Class A tag already had. - Shares rose by roughly the tagged magnitude. This is never forced to a forward split. A rising share count can be a real forward split, but it can just as easily be an IPO primary offering or heavy equity issuance, both of which move share count by a large factor with no split involved. A rise only confirms a split when the filer's own tag already said forward; it never invents one.
- No real cliff, or a cliff that matches neither the ratio nor its reciprocal. Trust the filer's tag as filed (or, for a filer that tagged the same event both ways in different filings, take the earliest-disclosed direction) rather than dropping a real event over a noisy or absent share-count observation.
One more guardrail matters before any of this runs: magnitude. Pre-IPO recapitalizations can tag conversion ratios in the millions (Elanco Animal Health tagged a founder-share conversion ratio of 2,932,900 ahead of its 2018 IPO), which is a legitimate XBRL fact but not a market split with public per-share history on both sides, so anything above roughly 1,000x is excluded outright. No real market split comes close; Chipotle's 50-for-1 in 2024 is the largest in our dataset.
Worked examples: what the detector flags, and what it deliberately doesn't
Pulled directly from /api/company/stock-splits for each ticker:
// Forward splits: tag and cliff agree, direction is not in question
GET /api/company/stock-splits?symbol=NVDA
[
{ "date": "2024-06-30", "ratio": 10, "type": "forward", "accession": "0001045810-24-000264", "firstDisclosedAt": "2024-08-28" },
{ "date": "2021-07-19", "ratio": 4, "type": "forward", "accession": "0001045810-21-000131", "firstDisclosedAt": "2021-08-20" }
]
// Reverse split, correctly resolved even though vTv's own 10-K tags the same event two ways
// in one filing — "0.025" for Class A, "40" (the untouched pre-split magnitude) for Class B —
// the share-count cliff resolves it independent of which tag a naive scan lands on
GET /api/company/stock-splits?symbol=VTVT
[
{ "date": "2023-11-20", "ratio": 0.025, "type": "reverse", "accession": "0001641489-24-000012", "firstDisclosedAt": "2024-03-13" }
]Ashford Hospitality Trust (AHT) is the clearest illustration of why reverse-split detection matters beyond just getting one date right. The hotel REIT executed three separate 1-for-10 reverse splits, in 2020, 2021, and 2024, each one to regain the NYSE's $1.00 minimum-price listing requirement. Looked at individually, each is a routine corporate action. Stacked, one AHT share today represents 1,000 pre-2020 shares, and a series of reverse splits at shrinking intervals is itself a signal worth surfacing to anyone screening for listing-compliance distress, not just a number to silently adjust away.
Equally important is what a correct detector refuses to flag. A rising share count from an IPO primary offering or a heavy secondary raise is never forced into a forward split, even when the magnitude happens to land near a round number, because trusting a rise without a filer's own tag would misclassify ordinary equity issuance as a corporate action that never happened.
Disclosure lag and date semantics: what firstDisclosedAt actually means
Two fields on every split record answer two different questions, and conflating them is a common bug. date is the split date as tagged in the XBRL footnote itself, typically the ex-date, record date, or payable date depending on the filer. firstDisclosedAt is the SEC acceptance date of the filing where that fact first became machine-readable, which can lag the actual event by weeks or, in one real case in our data, over a year and a half.
A few of these are worth reading closely. Amazon's tagged date of May 27, 2022 is its shareholder record date for the 20-for-1 split, not the June 6 trading-adjusted date. Alphabet's tagged date of July 15, 2022 is its distribution date; and because Alphabet disclosed the ratio in a subsequent-events footnote of its Q1 2022 10-Q, filed April 27, before the split even executed, its lag is negative, disclosed 89 days ahead of the event it describes. Different filers, different reference points, same concept, exactly the "date semantics vary by filer" caveat documented on the endpoint itself.
NVIDIA is the one worth being honest about rather than smoothing over: its tagged date for the 2024 split is 2024-06-30, which matches none of the split's three public dates, not the May 22 announcement, the June 6 record date, or the June 10 split-adjusted trading date. It lands on an ordinary calendar-quarter boundary, most likely a duration context the filer's tagging software defaulted to rather than a corporate-action date. It is a real caveat, not a bug we can parse around: for time-sensitive work, treat date as the tag's reported context, cross-check it against a primary source when the exact day matters, and never assume it equals a record, distribution, or trading date without checking which one a given filer used.
The Honest Company is the disclosure-lag outlier: its 2-for-1 split executed April 30, 2021, ahead of its May IPO, but the XBRL fact did not surface until a 10-Q filed November 10, 2022, 559 days later. A detector that only looks back 90 or even 180 days for a company's most recent split would have missed it entirely for a year and a half.
Detecting stock splits programmatically via the StockFit API
All of the above, XBRL fact extraction across two concepts and both plain and dimensional tagging, magnitude-based event clustering, share-count cliff corroboration, and the asymmetric drop-vs-rise logic, runs once per lake update and is served as a plain lookup, not recomputed per request. Three endpoints cover the three shapes of the problem:
- /api/company/stock-splits — full split history for one company, ordered newest first.
- /api/company/recent-stock-splits — market-wide feed of splits within a configurable lookback window (up to 365 days), useful for screening reverse-split candidates as a listing-compliance signal.
- /api/company/upcoming-stock-splits — declared splits not yet executed, sourced from a separate corporate-actions calendar rather than XBRL, since a split that has not happened yet cannot be in a filing.
curl "https://api.stockfit.io/v1/api/company/stock-splits?symbol=CMG" \
-H "Authorization: Bearer $STOCKFIT_TOKEN"Getting the split record right is not the end goal, it is the input to every other endpoint that has to stay consistent across a split boundary. /api/financials/income-statement and the other statement endpoints default to splitAdjust=true, applying the same corrected ratios so a five-year EPS or share-count series reads on one consistent basis instead of jumping 10x at a split date. Get the direction wrong once in the detector, and every downstream per-share figure before that date is wrong by the same factor, silently, which is exactly the class of error point-in-time backtesting work cannot tolerate.
The same multi-class dimensional tagging that hides a split ratio on the class_of_stock axis also hides EPS and share count for issuers like Visa; see extracting EPS and share count with Arelle for the as-converted reconstruction that problem needs. For the broader case of why any of this matters to a systematic strategy, see building a backtest on the StockFit API.
The underlying facts come from SEC EDGAR full-text search, and every split event StockFit resolves is parsed from the filing's own XBRL via Arelle, the open-source XBRL processor, rather than scraped from a calendar or press-release feed.
FAQ
Q.How do I detect stock splits in historical financial data?
us-gaap:StockholdersEquityNoteStockSplitConversionRatio1 and its predecessor) from each 10-K and 10-Q, including the copies tagged only on the class-of-stock dimension, then corroborate each candidate event against the company's own reported share-count history around that date. The tag alone tells you a split happened and roughly how large; the share-count cliff is what confirms the direction. StockFit runs this pipeline once per update and serves the result via /api/company/stock-splits.Q.Why can't I just look for a big overnight price jump to detect a split?
Q.Why does the XBRL stock-split ratio tag sometimes report the wrong direction?
0.025 for Class A and 40 for Class B, and The Honest Company tagged its 2021 split both ways across different filings. Trusting the raw sign of whichever tag a scan lands on first ships a wrong-direction event roughly as often as a filer contradicts itself.Q.What is a share-count cliff, and how does it confirm a stock split?
Q.Why do some companies take over a year to disclose a stock split in structured XBRL data?
Q.Can a rising share count ever be mistaken for a stock split?
Q.What is the difference between a forward and a reverse stock split?
Q.Are ETF and mutual fund share splits covered by the same stock-split endpoints?
Q.Which StockFit plan includes the stock split endpoints?
splitAdjust=true regardless of tier.Ready to build?
Free API key, no credit card. Every endpoint mentioned in this post is available on the free tier.