'Get info on multiple stock tickers quickly using yfinance

I am trying to get the current price and market cap of all of the tickers in the S&P500 and the way I am currently doing it is very slow, so I was wondering if there was anything I could do to improve it, or any other methods. Here is my current method, simply to print the name, market cap and current price:

import yfinance as yf

#I am using a csv file with a list of all the tickers which I use to create a pandas dataframe and form a space seperated string of all of the tickers called all_symbols
#I have simplified the pandas dataframe to a list for the purpose of this question

ticker_list = ["A", "AL", "AAP", "AAPL", ... "ZBRA", "ZION", "ZTS"]
all_symbols  = " ".join(ticker_list)

tickers = yf.Tickers(all_symbols)

for ticker in ticker_list:
    price = tickers.tickers[ticker].info["currentPrice"]
    market_cap = tickers.tickers[ticker].info["marketCap"]
    print(ticker, market_cap, price)

This method is currently very slow and the information is received one at a time, so is there anyway to make it faster and/or get the ticker info as a batch.

I have also tried using the yf.download method to download information on multiple tickers at once, and this was faster but I could not get the information I wanted from that, so is it possible to get the market cap and current price using the yf.download method?

Although there have been similar questions to this, they all seem to use the same general idea which I use, which takes a long time when the number of tickers is high, I am yet to find any solution which is faster than my current one, so any suggestions are appreciated, even solutions not using yfinance, as long as they get real-time data without a massive delay.



Solution 1:[1]

You may find that getting the values for a single ticker in a discrete thread will give you better overall performance. Here's an example:

import yfinance as yf
from concurrent.futures import ThreadPoolExecutor

def get_stats(ticker):
    info = yf.Tickers(ticker).tickers[ticker].info
    print(f"{ticker} {info['currentPrice']} {info['marketCap']}")

ticker_list = ['AAPL', 'ORCL', 'PREM.L', 'UKOG.L', 'KOD.L', 'TOM.L', 'VELA.L', 'MSFT', 'AMZN', 'GOOG']

with ThreadPoolExecutor() as executor:
    executor.map(get_stats, ticker_list)

Output:

VELA.L 0.035 6004320
UKOG.L 0.1139 18496450
PREM.L 0.461 89516976
ORCL 76.755 204970377216
MSFT 294.8669 2210578825216
TOM.L 0.604 10558403
KOD.L 0.3 47496900
AMZN 3152.02 1603886514176
AAPL 171.425 2797553057792
GOOG 2698.05 1784584732672

Solution 2:[2]

There is another library you can try called yahooquery. In my trial the time reduced from 34 seconds to 0.4 seconds.

from yahooquery import Ticker

ticker_list = ["A", "AL", "AAP", "AAPL", "ZBRA", "ZION", "ZTS"]
all_symbols = " ".join(ticker_list)
myInfo = Ticker(all_symbols)
myDict = myInfo.price

for ticker in ticker_list:
    ticker = str(ticker)
    longName = myDict[ticker]['longName']
    market_cap = myDict[ticker]['marketCap']
    price = myDict[ticker]['regularMarketPrice']
    print(ticker, longName, market_cap, price)

There are lots of other information in the myDict {} dictionary, check it out.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Albert Winestein
Solution 2 Penquin