How to Build Complete Price History Through Ticker Changes? Entity Resolution in Python
June 28, 2026
What's the question?
A ticker symbol is a label, not an identity. The symbol "FB" once belonged to BankBoston Corp, then Falcon Building Products, then FBR Asset Investment Corp, and finally Meta Platforms. The symbol "GM" belonged to General Motors Corporation until it went bankrupt in 2009, then to a legally distinct successor, General Motors Company, after its 2010 IPO. The symbol "DELL" belonged to Dell Inc until it went private in 2013, and then to Dell Technologies Inc when it re-listed in 2018.
Naively treating a ticker as a stable identifier creates silent data corruption. Stitching GM's pre-2009 price history onto the post-2010 entity produces a phantom return series that spans a bankruptcy — a series no investor could have actually held. Querying "FB" for a 20-year backtest might inadvertently pull BankBoston's 1970s bank stock data into a social media analysis.
Entity resolution is the process of mapping a ticker symbol to the specific legal entity it represented at a given point in time. Each entity has a unique identifier, a CIK (the SEC's Central Index Key), and a defined period during which it held the ticker. The same ticker can map to completely different companies in different eras.
The approach
- Use
xfl.resolve()to retrieve the full entity history for four tickers: META, FB, GM, and DELL - Confirm that META and FB both map to entity_id 2 (Meta Platforms Inc), proving the rename is correctly linked
- Show that GM maps to two entities with different CIKs — General Motors Corporation (CIK 0000040730, filed with the SEC until 2009) and General Motors Company (CIK 0001467858, filing from 2010 onward)
- Show that DELL maps to Dell Inc (entity 10408, traded 1988–2013) and Dell Technologies Inc (entity 65047, traded from 2018)
- Pull price data for each post-event entity to verify that the API returns data only for the correct legal entity
Code
import xfinlink as xfl
xfl.set_api_key("YOUR_API_KEY") # free at https://xfinlink.com/signup
tickers = ["META", "FB", "GM", "DELL"]
for t in tickers:
info = xfl.resolve(t)
entities = info["data"][t]["entities"]
print(f"\n{t} — {len(entities)} entity(ies):")
for e in entities:
end = e["ticker_valid_to"] or "present"
print(f" {e['name']} (entity {e['entity_id']}): "
f"{e['ticker_valid_from']} to {end}")
meta_entities = xfl.resolve("META")["data"]["META"]["entities"]
fb_entities = xfl.resolve("FB")["data"]["FB"]["entities"]
meta_id = meta_entities[0]["entity_id"]
fb_meta_id = [e["entity_id"] for e in fb_entities
if e["name"] == "Meta Platforms Inc"][0]
print(f"\nMETA entity_id: {meta_id}")
print(f"FB->Meta entity_id: {fb_meta_id}")
print(f"Same entity: {meta_id == fb_meta_id}")
gm_entities = xfl.resolve("GM")["data"]["GM"]["entities"]
for e in gm_entities:
end = e["ticker_valid_to"] or "present"
print(f"\nGM entity {e['entity_id']}: {e['name']}")
print(f" CIK: {e['cik']} | Ticker: {e['ticker_valid_from']} to {end}")
Full script with formatting and visualisation: entity-resolution-ticker-changes-python.py
Output
META — 1 entity(ies):
Meta Platforms Inc (entity 2): 2022-06-09 to present
FB — 4 entity(ies):
BANKBOSTON CORP (entity 809): 1971-01-07 to 1983-04-03
FALCON BUILDING PRODUCTS INC (entity 17829): 1994-11-03 to 1997-06-17
F B R ASSET INVESTMENT CORP (entity 28677): 1999-09-29 to 2003-03-28
Meta Platforms Inc (entity 2): 2012-05-18 to 2022-06-08
GM — 2 entity(ies):
General Motors Corporation (pre-2009 bankruptcy) (entity 4): 1962-07-02 to 2009-06-01
General Motors Company (entity 5): 2010-11-18 to present
DELL — 2 entity(ies):
DELL INC (entity 10408): 1988-06-22 to 2013-10-29
DELL TECHNOLOGIES INC (entity 65047): 2018-12-28 to present
META entity_id: 2
FB->Meta entity_id: 2
Same entity: True
GM entity 4: General Motors Corporation (pre-2009 bankruptcy)
CIK: 0000040730 | Ticker: 1962-07-02 to 2009-06-01
GM entity 5: General Motors Company
CIK: 0001467858 | Ticker: 2010-11-18 to present
What this tells us
The FB ticker has been assigned to four completely different companies since 1971. Only the most recent occupant is Meta Platforms. Entity resolution confirms that META (valid from 2022-06-09) and FB (valid for Meta from 2012-05-18 to 2022-06-08) both point to entity_id 2. This means any analysis that queries either ticker will correctly map to the same underlying company and its continuous history of SEC filings, financial statements, and price data.
GM illustrates a more consequential case. General Motors Corporation (entity 4) traded from 1962 until June 1, 2009, when it filed for Chapter 11 bankruptcy. Its equity was cancelled and its shareholders were wiped out. General Motors Company (entity 5) is a new legal entity that IPO'd on November 18, 2010, with a different CIK and no continuity of equity ownership from the predecessor. These are two distinct companies in the SEC's records. Treating them as one entity in a backtest would fabricate a return series that bridges a total loss event.
DELL presents a private-then-public gap. Dell Inc (entity 10408) was taken private by Michael Dell and Silver Lake Partners in October 2013. Dell Technologies Inc (entity 65047) returned to public markets in December 2018 after acquiring EMC Corporation and restructuring. There is a five-year gap with no public market data. Stitching the two price histories together would misrepresent the risk profile entirely — the original shareholders received a cash buyout at $13.65 per share, and the new entity debuted at an entirely different valuation.
So what?
Any quantitative workflow that uses ticker symbols as identifiers — backtests, factor models, screening pipelines, or risk systems — is vulnerable to entity confusion. The errors are silent: the data looks normal, the DataFrame has rows, and the numbers are plausible. The analysis is simply wrong.
Entity resolution should be the first step in any pipeline that spans multiple years. Before pulling prices or fundamentals, resolve the ticker to confirm which entity (or entities) it maps to and during which period. For GM, this means deciding whether the analysis covers the pre-bankruptcy or post-IPO entity. For DELL, it means acknowledging the five-year private gap. For FB/META, it means verifying the rename is correctly linked so the full 2012–present history is seamless.
The resolve endpoint returns entity identifiers, validity dates, CIK numbers, and index membership — everything needed to build a survivorship-bias-free dataset. Built from SEC EDGAR public filings and market data, this entity graph ensures that each row in a price or fundamentals DataFrame corresponds to the correct legal entity at the correct point in time.
Built with xfinlink — free financial data API for Python. pip install xfinlink
pip install xfinlink