In a previous post, I wrote about finding undervalued sectors in the stock market by determining the divergence of the sector from some representation of the market itself. This post was intended to be a starting point for an investor to determine which sectors (or which stocks belonging to a sector) might warrant a closer look. If you primarily invest in ETFs this is a pretty useful tool as you could invest in an ETF representing the sector if further research deemed that the sector is worthwhile of investment. However, for the investor in individual stocks it might not be as useful since, even when filtering at this level, there could still be hundreds of stocks to comb through.
In this post, a finer-toothed comb is used to dive deeper into each sector that makes up the stock market and using the same idea of divergence to determine if a stock might be undervalued (I’ll only be using S&P 500 tickers but you can use whatever data you’d like with slight modifications). As with the previous post, this is meant to be a starting point and not to be used as a primary investment criterion. The underlying fundamentals of a company that has underperformed its sector could be deteriorating making the stock cheap for a good reason (i.e. it might be going bankrupt). However, oftentimes good opportunities can be found in stocks that are disliked by Wall Street for inconsequential reasons or for no reason at all. Such stocks will likely begin to diverge from the sectors to which they belong.
Note that I will be using sectors rather than a representation of the market itself (e.g. the S&P 500 or the Russell 2000) since some sectors might grow faster or slower than the economy overall. Comparing the stocks from these sectors to the overall market would be an apples to oranges comparison. We can expect a stock to trade more closely to other stocks in its sector (which will all be similarly affected by the same economic conditions) than to the entire market. In essence, we’re using the stock to sector comparison to try and “filter out” some of the economic noise built into a stock price.
In this post, I will provide Python scripts that use the Polygon.io and Yahoo Finance APIs to gather market data, build market sectors, and find the divergence of (most) stocks in the S&P 500 from their sector. Two scripts are provided for analyzing the data. The first script iterates each sector and compares every stock in that sector to the sector average. This script produces many plots that can be looked through to find potential opportunities. The second script will look for a specified ticker in each sector and compare that single ticker to the sector average. The former script is for a broad search while the latter is for those seeking information about a particular company.
Fetching the Data
Polygon.io’s API was used to retrieve data pertaining to the sectors and industries each company in the S&P 500 belongs to. Unfortunately, since I’m using the free version of Polygon this takes a substantial amount of time. At the end of this post, I will include the CSV I created after fetching the data to save you the hassle. However, if you want to use a different collection of stocks in your analysis this script will have to be re-run substituting the filename containing your tickers with the S&P 500 ticker list that I used. Below is the Python script I used to gather this data.
import requests import pandas as pd import time if __name__ == '__main__': time.sleep(60) # just in case there were API calls before running tickers = pd.read_csv('sp500tickers.csv') # filename containing one column: symbols api_key = "<your key>" base_url = "https://api.polygon.io" detail_url = base_url + "/v1/meta/symbols/{ticker}/company?apiKey={key}" financial_url = base_url + "/v2/reference/financials/{ticker}?limit=1&type=Y&apiKey={key}" data = dict() data["ticker"] = [] data["industry"] = [] data["sector"] = [] tickers = tickers["symbol"].tolist() count = 0 for ticker in tickers: print("Processing {}; {} tickers out of {}.".format(ticker, count, len(tickers))) d_url = detail_url.format(key=api_key, ticker=ticker) d_json = requests.get(d_url).json() count += 1 if "industry" not in d_json or "sector" not in d_json: # was the data not available? did we submit too many requests? print(d_url, d_json) print("No results for {}".format(ticker)) time.sleep(60) count += 1 continue data["ticker"].append(ticker) data["industry"].append(d_json["industry"]) data["sector"].append(d_json["sector"]) if count % 5 == 0 and count > 0: # 5 calls/min for free Polygon.io time.sleep(60) print(data) output = pd.DataFrame.from_dict(data) output.to_csv("sector_data.csv", index=False)
If you plan on running this script the “<your key>” string value will need to be replaced with the API key you get from Polygon. You’ll notice several sleep statements throughout this script. Due to the “5 calls per minute” limit for the free version of Polygon I needed to wait a substantial amount of time to generate this dataset. However, two of the sleep statements are more cautionary than required and, if you happen to pay for Polygon ($99/mo) you won’t need to sleep at all.
The only thing this script does is make sequential calls to Polygon’s Ticker Details API endpoint to retrieve the sector and the industry for all of the tickers in the S&P 500. The results are written to a file sector_data.csv with three columns: ticker, industry, and sector. In the actual analysis, price data will be aggregated for the tickers via a Yahoo Finance API I created in Python.
All Ticker Analysis
In this analysis, a price for each sector is aggregated by taking the average normalized price of each stock in the sector. That is, min-max normalization is performed on each sector’s constituent stocks’ prices. The normalized stock prices become
Here, min(x) and max(x) are the minimum and maximum closing prices throughout an individual stock’s price history, respectively. This type of normalization takes each stocks’ price history and scales every value between 0 and 1 so that each stock considered is on a level playing field, i.e. the actual price of the stock doesn’t matter. Once this is done for each stock in a sector the average price on each day is used to represent the sector’s price.
Below is the Python logic up to this point.
sector_data = pd.read_csv("sector_data.csv") api = YahooFinanceAPI() # get tickers for each distinct sector s_data = {} for _, row in sector_data.iterrows(): if row["sector"] in s_data: s_data[row["sector"]].append(row["ticker"]) else: s_data[row["sector"]] = [row["ticker"]] sector_avgs = {} ticker_close = {} # used to find divergence ignore_tickers = [] edate = datetime.datetime.now() # data start date sdate = edate - relativedelta(years=5) # data end date day_length = {} for sector in s_data: # process each sector print("Processing sector: {}".format(sector)) # create directory for image output if need be pathlib.Path('plots/{}'.format(sector)).mkdir(parents=True, exist_ok=True) # grab the tickers for this sector tickers = s_data[sector] print("\tNumber of samples: {}".format(len(tickers))) all_close = {} # used to calculate averages count = 0 for ticker in tickers: ticker_data = None try: # get price data for the ticker from Yahoo Finance ticker_data = api.get_ticker_data(ticker, sdate, edate) except: print("\t\tNo data for ticker {}".format(ticker)) ignore_tickers.append(ticker) # no data, ignore the ticker continue # normalize the close price data ticker_data["Close"] = (ticker_data["Close"]-ticker_data["Close"].min())/ \ (ticker_data["Close"].max()-ticker_data["Close"].min()) all_close[ticker] = ticker_data["Close"].tolist() ticker_close[ticker] = ticker_data["Close"].tolist() count += 1 if count % 10 == 0: print("\t\tProcessed {} tickers".format(count)) # used to determine if all of the data was fetched for a ticker # the most number of days fetched is the length of data we want max_days = 0 for ticker in all_close: max_days = max_days if max_days > len(all_close[ticker]) else len(all_close[ticker]) day_length[sector] = max_days ## remove tickers that don't have X years worth of data good_tickers = {} for ticker in all_close: if len(all_close[ticker]) == max_days: good_tickers[ticker] = all_close[ticker] print("\tUsing {} out of {} tickers for sector average.".format(len(good_tickers), len(all_close))) # compute the average price for each day in the series # this is the "Sector's Closing Price" avg_close = [0 for _ in range(max_days)] for i in range(max_days): for ticker in good_tickers: # add up the normalized close prices avg_close[i] += good_tickers[ticker][i] # divide by the number of tickers in the sector to get the average avg_close = [avg / len(good_tickers) for avg in avg_close] sector_avgs[sector] = avg_close
The logic above will create a dictionary that maps a sector to its closing price data, i.e. the average closing price of all of the stocks that make up the sector. With this information, we can calculate the divergence of each stock in the sector from the sector and plot the results. Note that we are looking for times when the normalized price of the stocks trades below the sector’s normalized price.
for sector in s_data: alldf = pd.DataFrame(sector_avgs[sector], columns=["Close"]) max_days = day_length[sector] for ticker in s_data[sector]: if ticker not in ticker_close: # could not fetch data continue if len(ticker_close[ticker]) != max_days: # not enough data continue # compute the stock-sector divergence tickerdf = pd.DataFrame(ticker_close[ticker], columns=["Close"]) divergence = tickerdf["Close"] - alldf["Close"] # this is pretty crude, if the sum of the divergence over # the last 10 days is negative, i.e. recently the stock has # traded below the sector, we label the plot as UNDERVALUED # otherwise it is marked as OVERVALUED score = "UNDERVALUED" if (sum(divergence[-10:])/len(divergence[-10:])) > 0: score = "OVERVALUED" # 0-max_days used for x-axis (should really use dates) x = [x for x in range(max_days)] # plot the data plt.title("{} vs Sector ({})".format(ticker, sector)) div, = plt.plot(x, divergence, label="Divergence") sectorplt, = plt.plot(x, alldf["Close"], label="Avg. Sector Close") toiplt, = plt.plot(x, tickerdf["Close"], label="{} Close".format(ticker)) plt.legend(handles=[div, sectorplt, toiplt]) plt.fill_between(x, 0, 1, alpha=0.2, facecolor='red') plt.fill_between(x, 0, -1, alpha=0.2, facecolor='green') plt.savefig("plots/{}/{}_{}_{}.png".format(sector, score, ticker, sector)) plt.clf() # clear the plot area
Running this full script will produce a “plots” directory and one subdirectory for each sector. Within these subdirectories, there will be plotted results for each ticker in the sector. For example, the Communications sector only had data available for 8 stocks so it is the smallest sector analyzed thus the easiest to visualize. The screenshot below shows the directory structure for this sector:

As seen above, there are two stocks in the sector that were labeled as UNDERVALUED and six as OVERVALUED. Here’s a look at the plots for Verizon (VZ) [overvalued] and AT&T (T) [undervalued]:


As shown in these plots, VZ is trading fairly close to the sector average and, many times, above the sector average while T has dropped (due to the Covid-19 pandemic) and failed to recover.
Note that this doesn’t mean that Verizon is a sell and AT&T is a buy. AT&T does have a few operational issues that are of note and Verizon is largely regarded as the better stock in this industry. However, I don’t have in-depth knowledge of either company’s financial and fundamental positions so “I don’t know” would be my conclusion here. However, AT&T having diverged from its sector indicates that, if the stock warrants investment, it might have some upside potential when its valuation “catches up” with the sector (if that were to happen).
Single Ticker Analysis
Much of this analysis is the same as that done for the All Data analysis. The sector prices are determined in the same way, the stock price data is still min-max normalized, and the plots are created in the same way as well. The only difference is that it’s much faster since it only processes one ticker: the Ticker Of Interest (the toi variable in the script). Each sector is searched for the ticker of interest and, once it’s found, the sector’s average closing price and the stock-sector divergence are computed. A plot is then created just like what was done above. Because of the similarities, I will just provide the Python logic with comments sans the explanation and examples.
import pandas as pd from yfapi import YahooFinanceAPI import datetime from dateutil.relativedelta import relativedelta import matplotlib.pyplot as plt if __name__ == '__main__': sector_data = pd.read_csv("sector_data.csv") api = YahooFinanceAPI() s_data = {} i_data = {} for _, row in sector_data.iterrows(): if row["sector"] in s_data: s_data[row["sector"]].append(row["ticker"]) else: s_data[row["sector"]] = [row["ticker"]] # TODO: change ticker here to your ticker of interest toi = "LMT" edate = datetime.datetime.now() sdate = edate - relativedelta(years=10) all_close = {} toi_close = None sector = "<Sector>" for key in s_data: if toi in s_data[key]: sector = key tickers = s_data[key] print("Number of samples: {}".format(len(tickers))) count = 0 for ticker in tickers: ticker_data = None try: ticker_data = api.get_ticker_data(ticker, sdate, edate) except: print("\tNo data for ticker {}".format(ticker)) continue ticker_data["Close"] = (ticker_data["Close"]-ticker_data["Close"].min())/ \ (ticker_data["Close"].max()-ticker_data["Close"].min()) all_close[ticker] = ticker_data["Close"].tolist() if ticker == toi: toi_close = ticker_data["Close"].tolist() count += 1 if count % 10 == 0: print("\tProcessed {} tickers".format(count)) break max_days = 0 for ticker in all_close: max_days = max_days if max_days > len(all_close[ticker]) else len(all_close[ticker]) ## remove tickers that don't have X years worth of data good_tickers = {} for ticker in all_close: if len(all_close[ticker]) == max_days: good_tickers[ticker] = all_close[ticker] print("Using {} out of {} tickers for sector average.".format(len(good_tickers), len(all_close))) # calculate the sectors closing price avg_close = [0 for _ in range(max_days)] for i in range(max_days): for ticker in good_tickers: avg_close[i] += good_tickers[ticker][i] avg_close = [avg / len(good_tickers) for avg in avg_close] # find the divergence values alldf = pd.DataFrame(avg_close, columns=["Close"]) toidf = pd.DataFrame(toi_close, columns=["Close"]) divergence = toidf["Close"] - alldf["Close"] # plot the results as was done above x = [x for x in range(max_days)] plt.title("{} vs Sector ({})".format(toi, sector)) div, = plt.plot(x, divergence, label="Divergence") sector, = plt.plot(x, avg_close, label="Avg. Sector Close") toiplt, = plt.plot(x, toi_close, label="{} Close".format(toi)) plt.legend(handles=[div, sector, toiplt]) plt.fill_between(x, 0, 1, alpha=0.2, facecolor='red') plt.fill_between(x, 0, -1, alpha=0.2, facecolor='green') plt.show()
Conclusion
As with my sector-market divergence post, investment decisions should not be made based on this information alone. An investor should determine if the stock is worthy of investment by i) understanding any problems in the company and ii) understanding why the stock has diverged from the sector. Is the company still fundamentally solid? Are revenues and earnings declining? Is the company on the brink of bankruptcy? Does the company have growth prospects? These are a few of the questions that should be answered before taking this analysis very seriously. However, this divergence is a good tool in your investment toolkit since it provides leads to potentially undervalued stocks without having to search through the hundreds or thousands of stocks in the entire market. If good, solid companies have diverged from their sector and still have growth prospects they can oftentimes lead to strong capital gains when they become fully valued. Again, as I’ve stressed throughout the post, this should be taken as a starting point when looking for potential investments.
One potential issue to be aware of is that for smaller sectors the analysis might not be as useful. This is because there are so few stocks making up the sector that the sector’s closing price (i.e. the average normalized closing price of each stock in the sector) is more dependent on each individual stock.
Full Code
single_ticker.py
import pandas as pd from yfapi import YahooFinanceAPI import datetime from dateutil.relativedelta import relativedelta import matplotlib.pyplot as plt if __name__ == '__main__': sector_data = pd.read_csv("sector_data.csv") api = YahooFinanceAPI() s_data = {} for _, row in sector_data.iterrows(): if row["sector"] in s_data: s_data[row["sector"]].append(row["ticker"]) else: s_data[row["sector"]] = [row["ticker"]] toi = "LMT" edate = datetime.datetime.now() sdate = edate - relativedelta(years=10) all_close = {} toi_close = None sector = "<Sector>" for key in s_data: if toi in s_data[key]: sector = key tickers = s_data[key] print("Number of samples: {}".format(len(tickers))) count = 0 for ticker in tickers: ticker_data = None try: ticker_data = api.get_ticker_data(ticker, sdate, edate) except: print("\tNo data for ticker {}".format(ticker)) continue ticker_data["Close"] = (ticker_data["Close"]-ticker_data["Close"].min())/ \ (ticker_data["Close"].max()-ticker_data["Close"].min()) all_close[ticker] = ticker_data["Close"].tolist() if ticker == toi: toi_close = ticker_data["Close"].tolist() count += 1 if count % 10 == 0: print("\tProcessed {} tickers".format(count)) break max_days = 0 for ticker in all_close: max_days = max_days if max_days > len(all_close[ticker]) else len(all_close[ticker]) ## remove tickers that don't have X years worth of data good_tickers = {} for ticker in all_close: if len(all_close[ticker]) == max_days: good_tickers[ticker] = all_close[ticker] print("Using {} out of {} tickers for sector average.".format(len(good_tickers), len(all_close))) avg_close = [0 for _ in range(max_days)] for i in range(max_days): for ticker in good_tickers: avg_close[i] += good_tickers[ticker][i] avg_close = [avg / len(good_tickers) for avg in avg_close] alldf = pd.DataFrame(avg_close, columns=["Close"]) toidf = pd.DataFrame(toi_close, columns=["Close"]) divergence = toidf["Close"] - alldf["Close"] x = [x for x in range(max_days)] plt.title("{} vs Sector ({})".format(toi, sector)) div, = plt.plot(x, divergence, label="Divergence") sector, = plt.plot(x, avg_close, label="Avg. Sector Close") toiplt, = plt.plot(x, toi_close, label="{} Close".format(toi)) plt.legend(handles=[div, sector, toiplt]) plt.fill_between(x, 0, 1, alpha=0.2, facecolor='red') plt.fill_between(x, 0, -1, alpha=0.2, facecolor='green') plt.show()
all_tickers.py
import pandas as pd from yfapi import YahooFinanceAPI import datetime from dateutil.relativedelta import relativedelta import matplotlib.pyplot as plt import pathlib if __name__ == '__main__': sector_data = pd.read_csv("sector_data.csv") api = YahooFinanceAPI() s_data = {} for _, row in sector_data.iterrows(): if row["sector"] in s_data: s_data[row["sector"]].append(row["ticker"]) else: s_data[row["sector"]] = [row["ticker"]] sector_avgs = {} ticker_close = {} # used to find divergence ignore_tickers = [] edate = datetime.datetime.now() sdate = edate - relativedelta(years=5) day_length = {} for sector in s_data: print("Processing sector: {}".format(sector)) # create directory for image output if need be pathlib.Path('plots/{}'.format(sector)).mkdir(parents=True, exist_ok=True) tickers = s_data[sector] print("\tNumber of samples: {}".format(len(tickers))) all_close = {} # used to calculate averages count = 0 for ticker in tickers: ticker_data = None try: ticker_data = api.get_ticker_data(ticker, sdate, edate) except: print("\t\tNo data for ticker {}".format(ticker)) ignore_tickers.append(ticker) continue ticker_data["Close"] = (ticker_data["Close"]-ticker_data["Close"].min())/ \ (ticker_data["Close"].max()-ticker_data["Close"].min()) all_close[ticker] = ticker_data["Close"].tolist() ticker_close[ticker] = ticker_data["Close"].tolist() count += 1 if count % 10 == 0: print("\t\tProcessed {} tickers".format(count)) max_days = 0 for ticker in all_close: max_days = max_days if max_days > len(all_close[ticker]) else len(all_close[ticker]) day_length[sector] = max_days ## remove tickers that don't have X years worth of data good_tickers = {} for ticker in all_close: if len(all_close[ticker]) == max_days: good_tickers[ticker] = all_close[ticker] print("\tUsing {} out of {} tickers for sector average.".format(len(good_tickers), len(all_close))) avg_close = [0 for _ in range(max_days)] for i in range(max_days): for ticker in good_tickers: avg_close[i] += good_tickers[ticker][i] avg_close = [avg / len(good_tickers) for avg in avg_close] sector_avgs[sector] = avg_close for sector in s_data: alldf = pd.DataFrame(sector_avgs[sector], columns=["Close"]) max_days = day_length[sector] for ticker in s_data[sector]: if ticker not in ticker_close: # could not fetch data continue if len(ticker_close[ticker]) != max_days: # not enough data continue tickerdf = pd.DataFrame(ticker_close[ticker], columns=["Close"]) divergence = tickerdf["Close"] - alldf["Close"] score = "UNDERVALUED" if (sum(divergence[-10:])/len(divergence[-10:])) > 0: score = "OVERVALUED" x = [x for x in range(max_days)] plt.title("{} vs Sector ({})".format(ticker, sector)) div, = plt.plot(x, divergence, label="Divergence") sectorplt, = plt.plot(x, alldf["Close"], label="Avg. Sector Close") toiplt, = plt.plot(x, tickerdf["Close"], label="{} Close".format(ticker)) plt.legend(handles=[div, sectorplt, toiplt]) plt.fill_between(x, 0, 1, alpha=0.2, facecolor='red') plt.fill_between(x, 0, -1, alpha=0.2, facecolor='green') plt.savefig("plots/{}/{}_{}_{}.png".format(sector, score, ticker, sector)) plt.clf()
fetch_data.py
import requests import pandas as pd import time if __name__ == '__main__': time.sleep(60) # just in case there were API calls before running tickers = pd.read_csv('sp500tickers.csv') # filename containing one column: symbols api_key = "<your key>" base_url = "https://api.polygon.io" detail_url = base_url + "/v1/meta/symbols/{ticker}/company?apiKey={key}" financial_url = base_url + "/v2/reference/financials/{ticker}?limit=1&type=Y&apiKey={key}" data = dict() data["ticker"] = [] data["industry"] = [] data["sector"] = [] tickers = tickers["symbol"].tolist() count = 0 for ticker in tickers: print("Processing {}; {} tickers out of {}.".format(ticker, count, len(tickers))) d_url = detail_url.format(key=api_key, ticker=ticker) d_json = requests.get(d_url).json() count += 1 if "industry" not in d_json or "sector" not in d_json: # was the data not available? did we submit too many requests? print(d_url, d_json) print("No results for {}".format(ticker)) time.sleep(60) count += 1 continue data["ticker"].append(ticker) data["industry"].append(d_json["industry"]) data["sector"].append(d_json["sector"]) if count % 5 == 0 and count > 0: # 5 calls/min for free Polygon.io time.sleep(60) print(data) output = pd.DataFrame.from_dict(data) output.to_csv("sector_data.csv", index=False)
sector_data.csv
ticker,industry,sector MMM,Industrial Products,Industrials ABT,Medical Devices,Healthcare ABBV,Drug Manufacturers,Healthcare ABMD,Medical Devices,Healthcare ACN,Application Software,Technology ATVI,Application Software,Technology ADBE,Application Software,Technology AMD,Semiconductors,Technology AAP,Retail - Apparel & Specialty,Consumer Cyclical AES,Utilities - Regulated,Utilities AFL,Insurance - Life,Financial Services A,Medical Diagnostics & Research,Healthcare APD,Chemicals,Basic Materials AKAM,Application Software,Technology ALK,Airlines,Industrials ALB,Chemicals,Basic Materials ARE,REITs,Real Estate ALXN,Biotechnology,Healthcare ALGN,Medical Devices,Healthcare ALLE,Consulting & Outsourcing,Industrials ADS,Credit Services,Financial Services LNT,Utilities - Regulated,Utilities ALL,Insurance - Property & Casualty,Financial Services GOOGL,Online Media,Technology GOOG,Online Media,Technology MO,Tobacco Products,Consumer Defensive AMZN,Retail - Apparel & Specialty,Consumer Cyclical AEE,Utilities - Regulated,Utilities AAL,Airlines,Industrials AEP,Utilities - Regulated,Utilities AXP,Credit Services,Financial Services AIG,Insurance,Financial Services AMT,Communication Services,Communication Services AWK,Utilities - Regulated,Utilities AMP,Asset Management,Financial Services ABC,Medical Distribution,Healthcare AME,Industrial Products,Industrials AMGN,Biotechnology,Healthcare APH,Computer Hardware,Technology ADI,Semiconductors,Technology ANSS,Application Software,Technology ANTM,Health Care Plans,Healthcare AON,Brokers & Exchanges,Financial Services AOS,Industrial Products,Industrials APA,Oil & Gas - E&P,Energy AIV,REITs,Real Estate AAPL,Computer Hardware,Technology AMAT,Semiconductors,Technology APTV,Autos,Consumer Cyclical ADM,Consumer Packaged Goods,Consumer Defensive ANET,Computer Hardware,Technology AJG,Brokers & Exchanges,Financial Services AIZ,Insurance,Financial Services T,Communication Services,Communication Services ATO,Utilities - Regulated,Utilities ADSK,Application Software,Technology ADP,Business Services,Industrials AZO,Retail - Apparel & Specialty,Consumer Cyclical AVB,REITs,Real Estate AVY,Industrial Products,Industrials BLL,Packaging & Containers,Consumer Cyclical BAC,Banks,Financial Services BK,Asset Management,Financial Services BAX,Medical Instruments & Equipment,Healthcare BDX,Medical Instruments & Equipment,Healthcare BR,Business Services,Industrials BBY,Retail - Apparel & Specialty,Consumer Cyclical BIIB,Biotechnology,Healthcare BLK,Asset Management,Financial Services BA,Aerospace & Defense,Industrials BWA,Autos,Consumer Cyclical BXP,REITs,Real Estate BSX,Medical Devices,Healthcare BMY,Drug Manufacturers,Healthcare AVGO,Semiconductors,Technology BR,Business Services,Industrials B,Industrial Products,Industrials CHRW,Transportation & Logistics,Industrials COG,Oil & Gas - E&P,Energy CDNS,Application Software,Technology CPB,Consumer Packaged Goods,Consumer Defensive COF,Credit Services,Financial Services CAH,Medical Distribution,Healthcare KMX,Autos,Consumer Cyclical CCL,Travel & Leisure,Consumer Cyclical CAT,Farm & Construction Machinery,Industrials CBOE,Brokers & Exchanges,Financial Services CDW,Application Software,Technology CE,Chemicals,Basic Materials CNC,Health Care Plans,Healthcare CNP,Utilities - Regulated,Utilities CTL,Communication Services,Communication Services CERN,Application Software,Technology CF,Agriculture,Basic Materials SCHW,Brokers & Exchanges,Financial Services CHTR,Communication Services,Communication Services CVX,Oil & Gas - Integrated,Energy CMG,Restaurants,Consumer Cyclical CB,Insurance - Property & Casualty,Financial Services CHD,Consumer Packaged Goods,Consumer Defensive CI,Health Care Plans,Healthcare CINF,Insurance - Property & Casualty,Financial Services CTAS,Business Services,Industrials CSCO,Communication Equipment,Technology C,Banks,Financial Services CFG,Banks,Financial Services CTXS,Application Software,Technology CLX,Consumer Packaged Goods,Consumer Defensive CME,Brokers & Exchanges,Financial Services CMS,Utilities - Regulated,Utilities KO,Beverages - Non-Alcoholic,Consumer Defensive CTSH,Application Software,Technology CL,Consumer Packaged Goods,Consumer Defensive CMCSA,Communication Services,Communication Services CMA,Banks,Financial Services CAG,Consumer Packaged Goods,Consumer Defensive CXO,Oil & Gas - E&P,Energy COP,Oil & Gas - E&P,Energy ED,Utilities - Regulated,Utilities STZ,Beverages - Alcoholic,Consumer Defensive COO,Medical Instruments & Equipment,Healthcare CPRT,Autos,Consumer Cyclical GLW,Computer Hardware,Technology COST,Retail - Defensive,Consumer Defensive COTY,Consumer Packaged Goods,Consumer Defensive CCI,REITs,Real Estate CSX,Transportation & Logistics,Industrials CMI,Industrial Products,Industrials CVS,Health Care Plans,Healthcare DHI,Homebuilding & Construction,Consumer Cyclical DHR,Medical Diagnostics & Research,Healthcare DRI,Restaurants,Consumer Cyclical DVA,Health Care Providers,Healthcare DE,Farm & Construction Machinery,Industrials DAL,Airlines,Industrials XRAY,Medical Instruments & Equipment,Healthcare DVN,Oil & Gas - E&P,Energy DXCM,Medical Diagnostics & Research,Healthcare FANG,Oil & Gas - E&P,Energy DLR,REITs,Real Estate DFS,Credit Services,Financial Services DISCA,Entertainment,Consumer Cyclical DISCK,Entertainment,Consumer Cyclical DISH,Communication Services,Communication Services DG,Retail - Defensive,Consumer Defensive DLTR,Retail - Defensive,Consumer Defensive D,Utilities - Regulated,Utilities DPZ,Restaurants,Consumer Cyclical DOV,Industrial Products,Industrials DOW,Chemicals,Basic Materials DTE,Utilities - Regulated,Utilities DUK,Utilities - Regulated,Utilities DRE,REITs,Real Estate DD,Chemicals,Basic Materials DXC,Application Software,Technology ETFC,Brokers & Exchanges,Financial Services EMN,Chemicals,Basic Materials ETN,Industrial Products,Industrials EBAY,Retail - Apparel & Specialty,Consumer Cyclical ECL,Chemicals,Basic Materials EIX,Utilities - Regulated,Utilities EW,Medical Devices,Healthcare EA,Application Software,Technology EMR,Industrial Products,Industrials ETR,Utilities - Regulated,Utilities EOG,Oil & Gas - E&P,Energy EFX,Business Services,Industrials EQIX,REITs,Real Estate EQR,REITs,Real Estate ESS,REITs,Real Estate EL,Consumer Packaged Goods,Consumer Defensive ES,Utilities - Regulated,Utilities RE,Insurance - Specialty,Financial Services EXC,Utilities - Regulated,Utilities EXPE,Travel & Leisure,Consumer Cyclical EXPD,Transportation & Logistics,Industrials EXR,REITs,Real Estate XOM,Oil & Gas - Integrated,Energy FFIV,Application Software,Technology FB,Online Media,Technology FAST,Industrial Distribution,Industrials FRT,REITs,Real Estate FDX,Transportation & Logistics,Industrials FIS,Business Services,Industrials FITB,Banks,Financial Services FE,Utilities - Regulated,Utilities FRC,Banks,Financial Services FISV,Business Services,Industrials FLT,Business Services,Industrials FLIR,Computer Hardware,Technology FLS,Industrial Products,Industrials FMC,Agriculture,Basic Materials F,Autos,Consumer Cyclical FTNT,Application Software,Technology FTV,Computer Hardware,Technology FBHS,Manufacturing - Apparel & Furniture,Consumer Cyclical FOXA,Entertainment,Consumer Cyclical FOX,Entertainment,Consumer Cyclical BEN,Asset Management,Financial Services FCX,Metals & Mining,Basic Materials GPS,Retail - Apparel & Specialty,Consumer Cyclical GRMN,Computer Hardware,Technology IT,Application Software,Technology GD,Aerospace & Defense,Industrials GE,Industrial Products,Industrials GIS,Consumer Packaged Goods,Consumer Defensive GM,Autos,Consumer Cyclical GPC,Retail - Apparel & Specialty,Consumer Cyclical GILD,Biotechnology,Healthcare GPN,Business Services,Industrials GS,Brokers & Exchanges,Financial Services GWW,Industrial Distribution,Industrials HRB,Personal Services,Consumer Cyclical HAL,Oil & Gas - Services,Energy HBI,Manufacturing - Apparel & Furniture,Consumer Cyclical HOG,Autos,Consumer Cyclical HIG,Insurance,Financial Services HAS,Travel & Leisure,Consumer Cyclical HCA,Health Care Providers,Healthcare HSIC,Medical Distribution,Healthcare HSY,Consumer Packaged Goods,Consumer Defensive HES,Oil & Gas - E&P,Energy HPE,Communication Equipment,Technology HLT,Travel & Leisure,Consumer Cyclical HFC,Oil & Gas - Refining & Marketing,Energy HOLX,Medical Instruments & Equipment,Healthcare HD,Retail - Apparel & Specialty,Consumer Cyclical HON,Industrial Products,Industrials HRL,Consumer Packaged Goods,Consumer Defensive HST,REITs,Real Estate HPQ,Computer Hardware,Technology HUM,Health Care Plans,Healthcare HBAN,Banks,Financial Services HII,Aerospace & Defense,Industrials IEX,Industrial Products,Industrials IDXX,Medical Diagnostics & Research,Healthcare INFO,Business Services,Industrials ITW,Industrial Products,Industrials ILMN,Medical Diagnostics & Research,Healthcare INCY,Biotechnology,Healthcare IR,Industrial Products,Industrials INTC,Semiconductors,Technology ICE,Brokers & Exchanges,Financial Services IBM,Application Software,Technology IP,Packaging & Containers,Consumer Cyclical IPG,Advertising & Marketing Services,Consumer Cyclical IFF,Chemicals,Basic Materials INTU,Application Software,Technology ISRG,Medical Instruments & Equipment,Healthcare IVZ,Asset Management,Financial Services IPGP,Semiconductors,Technology IQV,Medical Diagnostics & Research,Healthcare IRM,Business Services,Industrials JKHY,Business Services,Industrials JBHT,Transportation & Logistics,Industrials SJM,Consumer Packaged Goods,Consumer Defensive JNJ,Drug Manufacturers,Healthcare JCI,Engineering & Construction,Industrials JPM,Banks,Financial Services JNPR,Communication Equipment,Technology KSU,Transportation & Logistics,Industrials K,Consumer Packaged Goods,Consumer Defensive KEY,Banks,Financial Services KEYS,Computer Hardware,Technology KMB,Consumer Packaged Goods,Consumer Defensive KIM,REITs,Real Estate KMI,Oil & Gas - Midstream,Energy KLAC,Semiconductors,Technology KSS,Retail - Apparel & Specialty,Consumer Cyclical KHC,Consumer Packaged Goods,Consumer Defensive KR,Retail - Defensive,Consumer Defensive LB,Retail - Apparel & Specialty,Consumer Cyclical LH,Medical Diagnostics & Research,Healthcare LRCX,Semiconductors,Technology LW,Consumer Packaged Goods,Consumer Defensive LVS,Travel & Leisure,Consumer Cyclical LEG,Manufacturing - Apparel & Furniture,Consumer Cyclical LDOS,Application Software,Technology LEN,Homebuilding & Construction,Consumer Cyclical LLY,Drug Manufacturers,Healthcare LNC,Insurance - Life,Financial Services LYV,Entertainment,Consumer Cyclical LKQ,Autos,Consumer Cyclical LMT,Aerospace & Defense,Industrials L,Insurance - Property & Casualty,Financial Services LOW,Retail - Apparel & Specialty,Consumer Cyclical LYB,Chemicals,Basic Materials MTB,Banks,Financial Services MRO,Oil & Gas - E&P,Energy MPC,Oil & Gas - Refining & Marketing,Energy MKTX,Brokers & Exchanges,Financial Services MAR,Travel & Leisure,Consumer Cyclical MMC,Brokers & Exchanges,Financial Services MLM,Building Materials,Basic Materials MAS,Building Materials,Basic Materials MA,Credit Services,Financial Services MKC,Consumer Packaged Goods,Consumer Defensive MXIM,Semiconductors,Technology MCD,Restaurants,Consumer Cyclical MCK,Medical Distribution,Healthcare MDT,Medical Devices,Healthcare MRK,Drug Manufacturers,Healthcare MET,Insurance - Life,Financial Services MTD,Medical Diagnostics & Research,Healthcare MGM,Travel & Leisure,Consumer Cyclical MCHP,Semiconductors,Technology MU,Semiconductors,Technology MSFT,Application Software,Technology MAA,REITs,Real Estate MHK,Manufacturing - Apparel & Furniture,Consumer Cyclical TAP,Beverages - Alcoholic,Consumer Defensive MDLZ,Consumer Packaged Goods,Consumer Defensive MNST,Beverages - Non-Alcoholic,Consumer Defensive MCO,Brokers & Exchanges,Financial Services MS,Brokers & Exchanges,Financial Services MOS,Agriculture,Basic Materials MSI,Communication Equipment,Technology MSCI,Brokers & Exchanges,Financial Services MYL,Drug Manufacturers,Healthcare NDAQ,Brokers & Exchanges,Financial Services NOV,Oil & Gas - Services,Energy NTAP,Computer Hardware,Technology NFLX,Entertainment,Consumer Cyclical NWL,Consumer Packaged Goods,Consumer Defensive NEM,Metals & Mining,Basic Materials NWSA,Entertainment,Consumer Cyclical NWS,Entertainment,Consumer Cyclical NEE,Utilities - Regulated,Utilities NLSN,Business Services,Industrials NKE,Manufacturing - Apparel & Furniture,Consumer Cyclical NI,Utilities - Regulated,Utilities NBL,Oil & Gas - E&P,Energy JWN,Retail - Apparel & Specialty,Consumer Cyclical NSC,Transportation & Logistics,Industrials NTRS,Asset Management,Financial Services NOC,Aerospace & Defense,Industrials NCLH,Travel & Leisure,Consumer Cyclical NRG,Utilities - Independent Power Producers,Utilities NUE,Steel,Basic Materials NVDA,Semiconductors,Technology NVR,Homebuilding & Construction,Consumer Cyclical ORLY,Retail - Apparel & Specialty,Consumer Cyclical OXY,Oil & Gas - E&P,Energy ODFL,Transportation & Logistics,Industrials OMC,Advertising & Marketing Services,Consumer Cyclical OKE,Oil & Gas - Midstream,Energy ORCL,Application Software,Technology PCAR,Truck Manufacturing,Industrials PKG,Packaging & Containers,Consumer Cyclical PH,Industrial Products,Industrials PAYX,Business Services,Industrials PAYC,Application Software,Technology PYPL,Credit Services,Financial Services PNR,Industrial Products,Industrials PBCT,Banks,Financial Services PEP,Beverages - Non-Alcoholic,Consumer Defensive PKI,Medical Diagnostics & Research,Healthcare PRGO,Drug Manufacturers,Healthcare PFE,Drug Manufacturers,Healthcare PM,Tobacco Products,Consumer Defensive PSX,Oil & Gas - Refining & Marketing,Energy PNW,Utilities - Regulated,Utilities PXD,Oil & Gas - E&P,Energy PNC,Banks,Financial Services PPG,Chemicals,Basic Materials PPL,Utilities - Regulated,Utilities PFG,Insurance - Life,Financial Services PG,Consumer Packaged Goods,Consumer Defensive PGR,Insurance - Property & Casualty,Financial Services PLD,REITs,Real Estate PRU,Insurance - Life,Financial Services PEG,Utilities - Regulated,Utilities PSA,REITs,Real Estate PHM,Homebuilding & Construction,Consumer Cyclical PVH,Manufacturing - Apparel & Furniture,Consumer Cyclical QRVO,Semiconductors,Technology PWR,Engineering & Construction,Industrials QCOM,Semiconductors,Technology DGX,Medical Diagnostics & Research,Healthcare RL,Manufacturing - Apparel & Furniture,Consumer Cyclical RJF,Brokers & Exchanges,Financial Services O,REITs,Real Estate REG,REITs,Real Estate REGN,Biotechnology,Healthcare RF,Banks,Financial Services RSG,Waste Management,Industrials RMD,Medical Instruments & Equipment,Healthcare RHI,Employment Services,Industrials ROK,Industrial Products,Industrials ROL,Business Services,Industrials ROP,Industrial Products,Industrials ROST,Retail - Apparel & Specialty,Consumer Cyclical RCL,Travel & Leisure,Consumer Cyclical SPGI,Brokers & Exchanges,Financial Services CRM,Application Software,Technology SBAC,Communication Services,Communication Services SLB,Oil & Gas - Services,Energy STX,Computer Hardware,Technology SEE,Packaging & Containers,Consumer Cyclical SRE,Utilities - Regulated,Utilities NOW,Application Software,Technology SHW,Chemicals,Basic Materials SPG,REITs,Real Estate SWKS,Semiconductors,Technology SLG,REITs,Real Estate SNA,Industrial Products,Industrials SO,Utilities - Regulated,Utilities LUV,Airlines,Industrials SWK,Industrial Products,Industrials SBUX,Restaurants,Consumer Cyclical STT,Asset Management,Financial Services STE,Medical Instruments & Equipment,Healthcare SYK,Medical Devices,Healthcare SIVB,Banks,Financial Services SYF,Credit Services,Financial Services SNPS,Application Software,Technology SYY,Retail - Defensive,Consumer Defensive TMUS,Communication Services,Communication Services TROW,Asset Management,Financial Services TTWO,Application Software,Technology TPR,Retail - Apparel & Specialty,Consumer Cyclical TGT,Retail - Defensive,Consumer Defensive TEL,Computer Hardware,Technology FTI,Oil & Gas - Services,Energy TFX,Medical Instruments & Equipment,Healthcare TXN,Semiconductors,Technology TXT,Aerospace & Defense,Industrials TMO,Medical Diagnostics & Research,Healthcare TIF,Retail - Apparel & Specialty,Consumer Cyclical TJX,Retail - Apparel & Specialty,Consumer Cyclical TSCO,Retail - Apparel & Specialty,Consumer Cyclical TDG,Aerospace & Defense,Industrials TRV,Insurance - Property & Casualty,Financial Services TWTR,Online Media,Technology TSN,Consumer Packaged Goods,Consumer Defensive UDR,REITs,Real Estate ULTA,Retail - Apparel & Specialty,Consumer Cyclical USB,Banks,Financial Services UAA,Manufacturing - Apparel & Furniture,Consumer Cyclical UA,Manufacturing - Apparel & Furniture,Consumer Cyclical UNP,Transportation & Logistics,Industrials UAL,Airlines,Industrials UNH,Health Care Plans,Healthcare UPS,Transportation & Logistics,Industrials URI,Consulting & Outsourcing,Industrials UHS,Health Care Providers,Healthcare UNM,Insurance - Life,Financial Services VFC,Manufacturing - Apparel & Furniture,Consumer Cyclical VLO,Oil & Gas - Refining & Marketing,Energy VAR,Medical Instruments & Equipment,Healthcare VTR,REITs,Real Estate VRSN,Online Media,Technology VRSK,Business Services,Industrials VZ,Communication Services,Communication Services VRTX,Biotechnology,Healthcare V,Credit Services,Financial Services VNO,REITs,Real Estate VMC,Building Materials,Basic Materials WR,Utilities - Regulated,Utilities WAB,Transportation & Logistics,Industrials WMT,Retail - Defensive,Consumer Defensive WBA,Retail - Defensive,Consumer Defensive DIS,Entertainment,Consumer Cyclical WM,Waste Management,Industrials WAT,Medical Diagnostics & Research,Healthcare WEC,Utilities - Regulated,Utilities WFC,Banks,Financial Services WST,Medical Instruments & Equipment,Healthcare WDC,Computer Hardware,Technology WU,Credit Services,Financial Services WRK,Packaging & Containers,Consumer Cyclical WY,Forest Products,Basic Materials WHR,Manufacturing - Apparel & Furniture,Consumer Cyclical WMB,Oil & Gas - Midstream,Energy WLTW,Brokers & Exchanges,Financial Services WYNN,Travel & Leisure,Consumer Cyclical XEL,Utilities - Regulated,Utilities XRX,Application Software,Technology XLNX,Semiconductors,Technology XYL,Industrial Products,Industrials YUM,Restaurants,Consumer Cyclical ZBRA,Industrial Products,Industrials ZBH,Medical Devices,Healthcare ZION,Banks,Financial Services
sp500ticker.csv
symbol MMM ABT ABBV ABMD ACN ATVI ADBE AMD AAP AES AFL A APD AKAM ALK ALB ARE ALXN ALGN ALLE ADS LNT ALL GOOGL GOOG MO AMZN AMCR AEE AAL AEP AXP AIG AMT AWK AMP ABC AME AMGN APH ADI ANSS ANTM AON AOS APA AIV AAPL AMAT APTV ADM ANET AJG AIZ T ATO ADSK ADP AZO AVB AVY BKR BLL BAC BK BAX BDX BR BBY BIIB BLK BA BKNG BWA BXP BSX BMY AVGO BR B CHRW COG CDNS CPB COF CAH KMX CCL CARR CAT CBOE CBRE CDW CE CNC CNP CTL CERN CF SCHW CHTR CVX CMG CB CHD CI CINF CTAS CSCO C CFG CTXS CLX CME CMS KO CTSH CL CMCSA CMA CAG CXO COP ED STZ COO CPRT GLW CTVA COST COTY CCI CSX CMI CVS DHI DHR DRI DVA DE DAL XRAY DVN DXCM FANG DLR DFS DISCA DISCK DISH DG DLTR D DPZ DOV DOW DTE DUK DRE DD DXC ETFC EMN ETN EBAY ECL EIX EW EA EMR ETR EOG EFX EQIX EQR ESS EL EVRG ES RE EXC EXPE EXPD EXR XOM FFIV FB FAST FRT FDX FIS FITB FE FRC FISV FLT FLIR FLS FMC F FTNT FTV FBHS FOXA FOX BEN FCX GPS GRMN IT GD GE GIS GM GPC GILD GL GPN GS GWW HRB HAL HBI HOG HIG HAS HCA PEAK HSIC HSY HES HPE HLT HFC HOLX HD HON HRL HST HWM HPQ HUM HBAN HII IEX IDXX INFO ITW ILMN INCY IR INTC ICE IBM IP IPG IFF INTU ISRG IVZ IPGP IQV IRM JKHY J JBHT SJM JNJ JCI JPM JNPR KSU K KEY KEYS KMB KIM KMI KLAC KSS KHC KR LB LHX LH LRCX LW LVS LEG LDOS LEN LLY LNC LIN LYV LKQ LMT L LOW LYB MTB MRO MPC MKTX MAR MMC MLM MAS MA MKC MXIM MCD MCK MDT MRK MET MTD MGM MCHP MU MSFT MAA MHK TAP MDLZ MNST MCO MS MOS MSI MSCI MYL NDAQ NOV NTAP NFLX NWL NEM NWSA NWS NEE NLSN NKE NI NBL JWN NSC NTRS NOC NLOK NCLH NRG NUE NVDA NVR ORLY OXY ODFL OMC OKE ORCL OTIS PCAR PKG PH PAYX PAYC PYPL PNR PBCT PEP PKI PRGO PFE PM PSX PNW PXD PNC PPG PPL PFG PG PGR PLD PRU PEG PSA PHM PVH QRVO PWR QCOM DGX RL RJF RTX O REG REGN RF RSG RMD RHI ROK ROL ROP ROST RCL SPGI CRM SBAC SLB STX SEE SRE NOW SHW SPG SWKS SLG SNA SO LUV SWK SBUX STT STE SYK SIVB SYF SNPS SYY TMUS TROW TTWO TPR TGT TEL FTI TFX TXN TXT TMO TIF TJX TSCO TT TDG TRV TFC TWTR TSN UDR ULTA USB UAA UA UNP UAL UNH UPS URI UHS UNM VFC VLO VAR VTR VRSN VRSK VZ VRTX VIAC V VNO VMC WR WAB WMT WBA DIS WM WAT WEC WFC WELL WST WDC WU WRK WY WHR WMB WLTW WYNN XEL XRX XLNX XYL YUM ZBRA ZBH ZION VYM VOO SPY