While browsing a variety of websites, I repeatedly observed significant fluctuations in the same financial metric among different sources. Similarly, the reported financial statements often didn't line up, and there was limited information on the methodology used to calculate each metric.
For example, Microsoft's Price-to-Earnings (PE) ratio on the 6th of May, 2023 is reported to be 28.93 (Stockopedia), 32.05 (Morningstar), 32.66 (Macrotrends), 33.09 (Finance Charts), 33.66 (Y Charts), 33.67 (Wall Street Journal), 33.80 (Yahoo Finance) and 34.4 (Companies Market Cap). All of these calculations are correct, however the method of calculation varies leading to different results. Therefore, collecting data from multiple sources can lead to wrong interpretation of the results given that one source could apply a different definition than another. And that is, if that definition is even available as often the underlying methods are hidden behind a paid subscription.
This is why I designed the FinanceToolkit, this is an open-source toolkit in which all relevant financial methods (500+) are written down in the most simplistic way allowing for complete transparency of the method of calculation (proof). This enables you to avoid dependence on metrics from other providers that do not provide their methods. With a large selection of financial statements in hand, it facilitates streamlined calculations, promoting the adoption of a consistent and universally understood methods and formulas.
Beyond Equities, it supports Options, Currencies, Cryptocurrencies, ETFs, Mutual Funds, Indices, Money Markets, Commodities, Key Economic Indicators and more, allowing you to obtain historical data as well as important performance and risk measurements such as the Sharpe Ratio and Value at Risk.
Complementing this is the Finance Database 🌎, a database featuring 300.000+ symbols containing Equities, ETFs, Funds, Indices, Currencies, Cryptocurrencies and Money Markets. By utilising both, it is possible to do a fully-fledged competitive analysis with the tickers found from the FinanceDatabase inputted into the FinanceToolkit.
🔌 The Finance Toolkit is also available as an MCP Server
Query 500+ methods from Claude, Copilot, Cursor, Windsurf or any MCP-compatible client without writing code.
- Hosted: connect to
https://financetoolkit.jeroenbouma.com/mcp— OAuth handles the rest on first use. - Local:
uvx --from "financetoolkit[mcp]" financetoolkit-mcp-setup— sets up your client config and API key automatically. See MCP Server Documentation for manual setup.
Also on Smithery, Glama, MCP Servers and more.
Before installation, consider starring the project on GitHub which helps others find the project as well.
To install the Finance Toolkit it simply requires the following:
pip install financetoolkit -U
Then within Python use:
from financetoolkit import Toolkit
companies = Toolkit(
tickers=['AAPL', 'MSFT'],
api_key="FINANCIAL_MODELING_PREP_KEY", # replace with your actual API key
)To be able to get started, you need to obtain an API Key from FinancialModelingPrep. This is used to gain access to 30+ years of financial statement both annually and quarterly. Note that the Free plan is limited to 250 requests each day, 5 years of data and only features companies listed on US exchanges.
Through the link you are able to subscribe for the free plan and also premium plans at a 15% discount. This is an affiliate link and thus supports the project at the same time. I have chosen FinancialModelingPrep as a source as I find it to be the most transparent, reliable and at an affordable price. I have yet to find a platform offering such low prices for the amount of data offered. When you notice that the data is inaccurate or have any other issue related to the data, note that I simply provide the means to access this data and I am not responsible for the accuracy of the data itself. For this, use their contact form or provide the data yourself.
By default, the Finance Toolkit prioritizes Financial Modeling Prep for data retrieval. If data acquisition from Financial Modeling Prep is unsuccessful (e.g., due to plan restrictions or API key issues), the toolkit automatically switches to Yahoo Finance as a secondary source. To disable this fallback behavior and exclusively use Financial Modeling Prep, set enforce_source="FinancialModelingPrep" during Toolkit initialization. This configuration ensures that an error is raised if Financial Modeling Prep data cannot be accessed. Alternatively, you can set enforce_source="YahooFinance" to exclusively use Yahoo Finance as the data source.
The same enforce_source argument is also accepted per call on get_historical_data, get_treasury_data and the four statement functions (get_balance_sheet_statement, get_income_statement, get_cash_flow_statement and get_statistics_statement), where it overrides whatever the Toolkit was initialised with.
This section is an introduction to the Finance Toolkit. The documentation contains many more examples: every module page opens with a Getting Started section, from the basics to creating custom ratios and working with your own datasets.
The sections below follow one analysis of the semiconductor sector from start to finish, where each step answers the question the previous one raises: which companies make up the sector, how their shares did, what drives their profits, how much risk came with the returns, what the option market expects next, how the economy shaped all of it, whether a fund is the better way in and how the sector fits into a diversified portfolio. Every module of the Finance Toolkit appears once, but each holds far more than shown here: 500+ methods in total, all described with examples in the documentation.
An analysis starts with a set of companies. The Discovery module finds them without needing any tickers yet, through stock screeners, sector performance, news and lists of companies, ETFs, indices, currencies, cryptocurrencies and commodities.
The screener below looks for semiconductor companies on NASDAQ that are worth more than $100 billion:
from financetoolkit import Discovery
# Initialize the standalone Discovery module
discovery = Discovery(api_key="FINANCIAL_MODELING_PREP_KEY")
# Find US semiconductor companies worth more than $100 billion
semiconductors = discovery.get_stock_screener(
industry="Semiconductors",
country="US",
exchange="NASDAQ",
market_cap_higher=100_000_000_000,
is_etf=False,
)
# Show the five largest
semiconductors[["Name", "Market Cap", "Beta", "Price", "Dividend"]].head()For example, the five largest companies the screener returns are shown below.
| Symbol | Name | Market Cap | Beta | Price | Dividend |
|---|---|---|---|---|---|
| NVDA | NVIDIA Corporation | 5084136000000 | 2.216 | 210.96 | 0.28 |
| AVGO | Broadcom Inc. | 1535581254973 | 1.476 | 321.68 | 2.6 |
| MU | Micron Technology, Inc. | 992877621000 | 2.226 | 877.55 | 0.565 |
| AMD | Advanced Micro Devices, Inc. | 843646776955 | 2.454 | 516.79 | 0 |
| INTC | Intel Corp. | 459679713584 | 2.23 | 86.96 | 0 |
And below all of them are ranked by market cap.
The rest of this walkthrough follows three of them: Nvidia, AMD and Intel. They are loaded into the Toolkit in one line, and the S&P 500 comes along as the benchmark:
from financetoolkit import Toolkit
# Initialize the Toolkit for Nvidia, AMD and Intel from 2018 to 2025
companies = Toolkit(
["NVDA", "AMD", "INTC"],
api_key="FINANCIAL_MODELING_PREP_KEY",
start_date="2017-12-31",
end_date="2025-12-31",
)Historical data comes on a daily, weekly, monthly, quarterly or yearly basis, with the return and cumulative return of each period, and so do the income statement, balance sheet and cash flow statement on an annual or quarterly basis. How far a share has travelled is one thing; whether the rally was stretched is another. The technicals module answers that with 50+ indicators, such as the Relative Strength Index (RSI), which moves between 0 and 100 and is commonly read as overbought above 70:
# Obtain weekly market data for all tickers and the benchmark
historical_data = companies.get_historical_data(period="weekly")
# The 14-week Relative Strength Index
relative_strength_index = companies.technicals.get_relative_strength_index(period="weekly", window=14)
# Show the highest RSI of each year
relative_strength_index.groupby(relative_strength_index.index.start_time.year).max()For example, the highest weekly RSI of each year is shown below.
| Date | NVDA | AMD | INTC | Benchmark |
|---|---|---|---|---|
| 2018 | 66.1087 | 90.9719 | 66.7363 | 66.0498 |
| 2019 | 73.8156 | 81.2446 | 69.8225 | 75.9305 |
| 2020 | 85.2337 | 82.1215 | 78.4827 | 80.2378 |
| 2021 | 85.1593 | 82.0983 | 71.5862 | 74.4751 |
| 2022 | 58.4343 | 58.9426 | 61.2806 | 59.9225 |
| 2023 | 87.5129 | 77.506 | 76.2332 | 71.4291 |
| 2024 | 91.0702 | 82.1403 | 67.6949 | 80.0566 |
| 2025 | 73.3514 | 82.5281 | 79.7429 | 71.6939 |
And below the cumulative returns of all three are plotted against the S&P 500, with the RSI underneath.
Nvidia's shares outran the other two by far, which raises the question whether its business did as well. From the financial statements the Toolkit calculates 80+ ratios in five categories: efficiency, liquidity, profitability, solvency and valuation. Each ratio has its own function, and a collect_ function returns a whole category at once:
# Collect all Profitability Ratios for all tickers
profitability_ratios = companies.ratios.collect_profitability_ratios()
# Show the first ratios for Nvidia
profitability_ratios.loc["NVDA"].head()For example, some of Nvidia's profitability ratios are shown below.
| 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | |
|---|---|---|---|---|---|---|---|---|---|
| Gross Margin | 0.5993 | 0.6121 | 0.6199 | 0.6234 | 0.6493 | 0.5693 | 0.7272 | 0.7499 | 0.7107 |
| Operating Margin | 0.3305 | 0.3247 | 0.2607 | 0.2718 | 0.3731 | 0.1566 | 0.5412 | 0.6242 | 0.6038 |
| Net Profit Margin | 0.3137 | 0.3534 | 0.2561 | 0.2598 | 0.3623 | 0.1619 | 0.4885 | 0.5585 | 0.556 |
| EBITDA Margin | 0.3509 | 0.347 | 0.2956 | 0.3376 | 0.4167 | 0.2138 | 0.566 | 0.6385 | 0.617 |
| Free Cash Flow Margin | 0.2995 | 0.2683 | 0.3913 | 0.2815 | 0.3021 | 0.1412 | 0.4435 | 0.4663 | 0.4477 |
And below a few of them are shown with their latest value and their course over the years.
A high return on equity can come from margins, from turnover or from debt. Models combine the ratios to tell these apart: the Extended DuPont Analysis splits the return on equity into five components that multiply into it: interest burden, tax burden, operating margin, asset turnover and equity multiplier.
# Get the Extended DuPont Analysis for all tickers
extended_dupont_analysis = companies.models.get_extended_dupont_analysis()
# Show the results for Nvidia
extended_dupont_analysis.loc["NVDA"]For example, the components for Nvidia are shown below.
| 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | 2023 | 2024 | 2025 | |
|---|---|---|---|---|---|---|---|---|---|
| Interest Burden Ratio | 0.9956 | 1.0242 | 1.0436 | 0.9729 | 0.99 | 0.9898 | 1.0257 | 1.0316 | 1.0848 |
| Tax Burden Ratio | 0.9534 | 1.0629 | 0.9414 | 0.9825 | 0.981 | 1.0447 | 0.88 | 0.8674 | 0.8488 |
| Operating Profit Margin | 0.3305 | 0.3247 | 0.2607 | 0.2718 | 0.3731 | 0.1566 | 0.5412 | 0.6242 | 0.6038 |
| Asset Turnover | 0.9215 | 0.9551 | 0.7134 | 0.7233 | 0.7376 | 0.6319 | 1.1397 | 1.4718 | 1.3564 |
| Equity Multiplier | 1.5931 | 1.4592 | 1.4205 | 1.5846 | 1.6775 | 1.7525 | 1.6428 | 1.4499 | 1.3456 |
| Return on Equity | 0.4605 | 0.4926 | 0.2595 | 0.2978 | 0.4483 | 0.1793 | 0.9146 | 1.1918 | 1.0149 |
And below each component is shown for every fiscal year, with the latest value on top, multiplying into the return on equity.
Other models include the Weighted Average Cost of Capital, Altman Z-Score, Piotroski F-Score and Intrinsic Valuation. Almost every function also accepts growth=True for the growth from one period to the next, trailing=4 for trailing twelve-month figures and standardize=True for Z-Scores.
Strong businesses do not make for smooth shares. The market data feeds the performance and risk modules, which calculate their metrics for any period, from intraday to yearly:
# The annualized Sharpe Ratio for each year
sharpe_ratio = companies.performance.get_sharpe_ratio(period="yearly", annualize=True)
# The deepest fall within each year
maximum_drawdown = companies.risk.get_maximum_drawdown(period="yearly", within_period=True)
# Show the Sharpe Ratios
sharpe_ratioFor example, the yearly Sharpe Ratios are shown below.
| Date | NVDA | AMD | INTC |
|---|---|---|---|
| 2018 | -0.613 | 1.1009 | 0.161 |
| 2019 | 1.5458 | 1.9143 | 1.048 |
| 2020 | 1.656 | 1.419 | -0.0445 |
| 2021 | 2.0003 | 1.2366 | 0.2976 |
| 2022 | -0.8393 | -1.0532 | -1.5306 |
| 2023 | 2.6986 | 1.9195 | 1.8358 |
| 2024 | 2.0851 | -0.2615 | -1.5749 |
| 2025 | 0.8325 | 1.1753 | 1.2061 |
And below both are plotted for each year, the maximum drawdown together with the S&P 500.
Together the two modules cover 70+ metrics, such as Value at Risk, GARCH, Jensen's Alpha, the Capital Asset Pricing Model and the Fama-French factors. Most of them also accept rolling=<n> for a value that moves through time.
The past shows how much risk came with the returns; the option market puts a price on the risk ahead. The options module prices options with Black-Scholes, the Binomial Model and others, calculates the Greeks up to the third order and reads the live option chains: the put-c






