The yfinance library pulls P/E, P/B, ROE, and debt-to-equity ratios for any stock without an API key. Twenty minutes. One script. A CSV file with your entire watchlist's fundamentals.
Key Takeaways
yfinanceprovides programmatic access to Yahoo Finance fundamental data without requiring authentication or paid subscriptions.- Extract trailing P/E, price-to-book, return on equity, and debt-to-equity ratios using the
.infodictionary attribute. - The script outputs a CSV file compatible with Excel, Google Sheets, or database imports for further analysis.
Before You Start
This guide assumes you can run Python scripts from a terminal and install packages using pip. The data returned by Yahoo Finance is delayed approximately 15 minutes during market hours and reflects the most recent quarterly or trailing twelve-month (TTM) filings available. That means this is not real-time data — it's what Yahoo Finance shows on its public quote pages, pulled programmatically.
What You Need
- Python 3.7 or later — verify by running
python --version - pip package manager (included with most Python installations)
- Internet connection to fetch live data from Yahoo Finance servers
- A text editor or IDE — VS Code, PyCharm, Sublime Text, or Notepad
- A list of ticker symbols you want to analyze (AAPL, MSFT, GOOGL, etc.)
Step 1: Install the yfinance Library
Open your terminal and run pip install yfinance. This installs the unofficial Yahoo Finance API wrapper maintained by Ran Aroussi. No authentication required. Wait until the command prompt returns before proceeding.
Step 2: Install pandas for Data Export
Run pip install pandas in the same terminal window. The pandas library provides the DataFrame structure that makes CSV export straightforward. This matters because manually formatting CSV output is error-prone — pandas handles quoting, delimiters, and encoding automatically.
Step 3: Create a New Python Script
Open your text editor and create a new file named extract_ratios.py. Save it in a folder where you have write permissions. At the top of the file, add:
import yfinance as yf
import pandas as pd
These lines load the libraries you installed. The as yf and as pd syntax creates shortcuts you will use throughout the script.
Step 4: Define Your Stock Watchlist
Below your imports, create a Python list containing the ticker symbols you want to analyze:
tickers = ['AAPL', 'MSFT', 'GOOGL', 'AMZN', 'TSLA']
Replace these with your actual watchlist. This list drives the entire script — each ticker gets queried sequentially. Keep the list under 50 tickers for the initial test to avoid rate-limiting issues.
Step 5: Write the Data Extraction Loop
Add this code block below your ticker list:
results = []
for ticker in tickers:
stock = yf.Ticker(ticker)
info = stock.info
results.append({
'Ticker': ticker,
'P/E Ratio': info.get('trailingPE', 'N/A'),
'Price/Book': info.get('priceToBook', 'N/A'),
'ROE': info.get('returnOnEquity', 'N/A'),
'Debt/Equity': info.get('debtToEquity', 'N/A')
})
This loop creates a Ticker object for each symbol, retrieves the .info dictionary, and extracts four ratios. The .get() method with 'N/A' as the default ensures your script does not crash if Yahoo Finance lacks data for a particular metric — common with newly listed companies or certain share classes.
Step 6: Export to CSV
After the loop completes, add these two lines:
df = pd.DataFrame(results)
df.to_csv('financial_ratios.csv', index=False)
The index=False parameter prevents pandas from adding an unnecessary row-number column. The CSV file appears in the same folder as your script. Opens directly in Excel or Google Sheets.
Step 7: Run the Script and Verify Output
Save your script and return to your terminal. Navigate to the folder containing extract_ratios.py using the cd command. Run python extract_ratios.py. You should see no output if the script executes successfully — errors print to the terminal. After execution, check for financial_ratios.csv in the folder. Open it to confirm the ticker symbols and ratio columns populated correctly.
Common Problems
ModuleNotFoundError: No module named 'yfinance' — The library did not install correctly or you are running Python from a different environment. Re-run pip install yfinance and verify you are using the same Python executable by running which python (macOS/Linux) or where python (Windows).
All ratios return 'N/A' for a specific ticker — Yahoo Finance may not have fundamental data for that symbol. Common with ETFs, foreign stocks on unsupported exchanges, or newly IPO'd companies. Verify the ticker is correct and check the stock's Yahoo Finance page manually.
Script runs slowly or times out — Yahoo Finance's free tier does not guarantee response times. If you are querying more than 100 tickers, add a delay between requests using import time and time.sleep(1) inside your loop.
What Most Guides Miss: Why This Matters for Portfolio Management
The real value here is not the script itself — it is what happens when you run this daily and store the results. Most retail investors check fundamentals manually, one stock at a time, on Yahoo Finance's website. That approach works fine for three positions. It breaks down at fifteen.
What you are building is a screening infrastructure. Run this script every morning before market open and append a timestamp column. Within thirty days you have a time-series dataset showing which stocks in your watchlist are experiencing P/E compression, ROE improvement, or debt ratio deterioration. That is not something Yahoo Finance's interface gives you without clicking through dozens of pages.
The deeper story: automated fundamental tracking separates investors who react to price movement from investors who understand what is changing beneath it. When $AAPL drops 8% in a session, you can open your CSV history and see whether the P/E dropped proportionally or whether the market is repricing based on something fundamental. That context does not appear on a stock screener.
Best Practices
- Always use
.get()with a default value when extracting metrics from the.infodictionary. Yahoo Finance data is inconsistent — a missing key crashes your script if you access it with bracket notation. - Add a timestamp column to your CSV by including
'Date': pd.Timestamp.now()in your results dictionary. This creates an audit trail if you run the script daily to track ratio changes over time. - Check for None values before calculations — some ratios return
Noneinstead of a number. Use conditional logic:if info.get('trailingPE') is not None. - Store your ticker list in a separate text file (one symbol per line) and load it using
open('tickers.txt').read().splitlines(). Makes updating your watchlist easier without editing the script. - Combine this with scheduled automation using cron (Linux/macOS) or Task Scheduler (Windows) to generate fresh ratio snapshots every morning before market open. For cloud-based scheduling, GitHub Actions provides a free alternative for running Python scripts on a timer.
When Not to Use This
This approach is not appropriate when you need real-time intraday data or historical fundamental snapshots from specific fiscal quarters. The yfinance library returns only the most recent trailing or quarterly figures — it does not provide time-series access to how P/E ratios changed over the past five years. For historical fundamental analysis, you need SEC EDGAR filings or a paid data provider.
Do not rely on this method for high-frequency trading or sub-second decision-making. Yahoo Finance introduces a 15-minute delay during market hours and does not guarantee uptime. If your strategy depends on live market prices or orderbook depth, use a broker API with official market data access.
Avoid using yfinance for production financial services or client-facing applications. Yahoo's terms of service restrict commercial use, and the library is an unofficial wrapper with no SLA or support guarantee. The maintainer could abandon the project, or Yahoo could change their data structure without notice, breaking your code. For compliance-sensitive environments, purchase a licensed data feed.
FAQ
How do I pull financial metrics with yfinance beyond the four ratios in this guide?
The .info dictionary contains over 100 fields including market cap (marketCap), forward P/E (forwardPE), beta (beta), dividend yield (dividendYield), and profit margin (profitMargins). Print the entire dictionary using print(stock.info) to see all available keys for a given ticker, then add the relevant keys to your results dictionary using the same .get() pattern.
How do I download company fundamentals for a large number of stocks efficiently?
For watchlists exceeding 200 tickers, batch your requests into groups of 50 and add a 2-second delay between batches using time.sleep(2). Store results in a database (SQLite is built into Python) instead of appending to a list, which prevents memory issues. Consider running the script during off-peak hours to reduce the chance of throttling.
How do I get the P/E ratio using the Yahoo Finance API when it shows as None?
A None value for trailingPE usually means the company reported negative earnings in the trailing twelve months, making the ratio undefined. Check info.get('forwardPE') instead, which uses analyst estimates for the next fiscal year. If both return None, the stock may be pre-revenue or Yahoo Finance lacks analyst coverage. Verify earnings data manually on the company's investor relations page or SEC filings.
Can I use this script to track ratios for international stocks?
Yes, but append the correct exchange suffix to the ticker symbol. Use 'HSBA.L' for HSBC on the London Stock Exchange or '7203.T' for Toyota on the Tokyo Stock Exchange. Yahoo Finance maintains a list of supported exchanges and their suffix codes on their help pages. Some international stocks return ratios in local currency — check the currency field in .info before comparing across regions.