Performance
The Performance module calculates important performance metrics such as the Sharpe Ratio, Sortino Ratio, Treynor Ratio, Information Ratio, Jensen’s Alpha, Beta, Capital Asset Pricing Model (CAPM), R-Squared and more.
To install the FinanceToolkit it simply requires the following:
pip install financetoolkit -U
collect_all_metrics
Calculates and collects all performance metrics.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Performance metrics calculated based on the specified parameters, with a
Multi Index of (metric, ticker) as the columns. For a single-ticker Toolkit the ticker
level is dropped. Returns and Excess Return are only included when period is not
“daily”.
Notes:
- The method calculates various performance metrics for each asset in the Toolkit instance.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.collect_all_metrics().xs("AAPL", level=1, axis=1)
Which returns:
| Win Rate | Upside Capture Ratio | Downside Capture Ratio | M2 Ratio | Tracking Error | |
|---|---|---|---|---|---|
| 2021 | 0.5253 | 1.4003 | 1.1039 | 0.0065 | 0.0108 |
| 2022 | 0.4781 | 1.3096 | 1.3186 | -0.1669 | 0.0115 |
| 2023 | 0.576 | 1.1815 | 0.9655 | 0.3293 | 0.009 |
| 2024 | 0.5 | 1.117 | 1.0492 | 0.1905 | 0.0121 |
| 2025 | 0.472 | 1.0324 | 1.1132 | 0.0709 | 0.0139 |
| 2026 | 0.5099 | 0.678 | 0.5418 | 0.0919 | 0.0169 |
get_beta
Calculate the Beta, a measurement that assess the systematic risk of a stock or investment.
Beta is a financial metric used to assess the systematic risk of a stock or investment in relation to the overall market. It provides valuable insights into how a particular asset’s returns tend to move in response to fluctuations in the broader market. A stock’s Beta is calculated by analyzing its historical price movements and their correlation with the movements of a market index, typically the benchmark index like the S&P 500.
The formula is as follows:
\[\text{Beta} = \text{Covariance of Asset Returns and Benchmark Returns} / \text{Variance of Benchmark Returns}\]For a given period, for example monthly, this translates into the following:
\[\text{Beta} = \text{Monthly Covariance of Asset Returns and Benchmark Returns} / \text{Monthly Variance of Benchmark Returns}\]See definition: https://en.wikipedia.org/wiki/Beta_(finance)
Also known as: market sensitivity, systematic risk.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rolling (int, optional): The rolling period to use for the calculation. If you select period = ‘monthly’ and set rolling to 12 you obtain the rolling 12-month Sharpe Ratio.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Beta values.
Notes:
- Daily Beta is not an option as the standard deviation for 1 day is close to zero. Therefore, it does not give any useful insights.
- The method retrieves historical data and calculates the Beta for each asset in the Toolkit instance.
- The risk-free rate is often represented by the return of a risk-free investment, such as a Treasury bond.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "AMZN"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_beta()
Which returns:
| Date | AAPL | AMZN |
|---|---|---|
| 2021 | 1.3093 | 1.0276 |
| 2022 | 1.2989 | 1.6292 |
| 2023 | 1.1 | 1.5133 |
| 2024 | 0.9656 | 1.5442 |
| 2025 | 1.2485 | 1.3264 |
| 2026 | 0.7887 | 1.281 |
get_capital_asset_pricing_model
CAPM, or the Capital Asset Pricing Model, is a financial model used to estimate the expected return on an investment, such as a stock or portfolio of stocks. It provides a framework for evaluating the risk and return trade-off of an asset or portfolio in relation to the overall market. CAPM is based on the following key components:
- Risk-Free Rate (Rf): This is the theoretical return an investor could earn from an investment with no risk of financial loss. It is typically based on the yield of a government bond.
- Market Risk Premium (Rm - Rf): This represents the additional return that investors expect to earn for taking on the risk of investing in the overall market as opposed to a risk-free asset. It is calculated as the difference between the expected return of the market (Rm) and the risk-free rate (Rf).
- Beta (β): Beta is a measure of an asset’s or portfolio’s sensitivity to market movements. It quantifies how much an asset’s returns are expected to move in relation to changes in the overall market. A beta of 1 indicates that the asset moves in line with the market, while a beta greater than 1 suggests higher volatility, and a beta less than 1 indicates lower volatility.
The Capital Asset Pricing Model (CAPM) is a widely used financial model that helps in determining the expected return of an asset or portfolio based on its systematic risk and the prevailing risk-free rate in the market. CAPM provides insights into how an asset or investment should be priced in order to offer an appropriate rate of return, given its level of risk compared to the overall market.
The formula is as follows:
\[\text{Capital Asset Pricing Model} = \text{Risk Free Rate} + \text{Beta} \cdot (\text{Benchmark Returns} - \text{Risk Free Rate})\]See definition: https://en.wikipedia.org/wiki/Capital_asset_pricing_model
Also known as: CAPM, expected return model.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rolling (int, optional): The rolling window size to use for the Beta component of the
calculation. If set, Beta is estimated over a rolling window of this many periods across
the full return history instead of per
period. Defaults to None. - rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: CAPM values.
Notes:
- Daily CAPM is not an option as the standard deviation for 1 day is close to zero. Therefore, it does not give any useful insights.
- The method retrieves historical data and calculates the CAPM for each asset in the Toolkit instance.
- The risk-free rate is often represented by the return of a risk-free investment, such as a Treasury bond.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_capital_asset_pricing_model()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | 0.3494 | 0.4914 |
| 2022 | -0.2646 | -0.3666 |
| 2023 | 0.2633 | 0.4905 |
| 2024 | 0.2266 | 0.4924 |
| 2025 | 0.1938 | 0.3135 |
| 2026 | 0.0822 | 0.1364 |
get_factor_asset_correlations
Calculates factor exposures for each asset.
The major difference between the Fama and French Model here is that the correlation is taken as opposed to a Linear Regression in which the R-squared or Slope can be used to understand the exposure to each factor.
For assessing the exposure or influence of a stock to external factors, it’s often preferable to use R-squared (R²) or Beta because it explicitly measures how well the factors explain the stock’s returns. A higher R² indicates that the stock’s returns are more closely related to the factors, and thus, the factors have a greater influence on the stock’s performance.
However, since the results are closely related and tend to point into the same direction it could be fine to use correlations as well depending on the level of accuracy required.
Also known as: factor exposure, asset correlations.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- factors_to_calculate (list of str, optional): List of factors to calculate scores and residuals for. Defaults to [“Mkt-RF”, “SMB”, “HML”, “RMW”, “CMA”].
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- show_columns (list of str, optional): Restrict the result to these top level columns. Defaults to None, which returns every column.
Returns:
pd.DataFrame: Factor Asset Correlations, with a Multi Index of (ticker, factor) as the columns and one row per period.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_factor_asset_correlations()["AAPL"]
Which returns:
| Mkt-RF | SMB | HML | RMW | CMA | |
|---|---|---|---|---|---|
| 2021 | 0.6626 | -0.0091 | -0.3248 | -0.0655 | -0.0029 |
| 2022 | 0.8796 | 0.0561 | -0.5479 | -0.2577 | -0.4763 |
| 2023 | 0.6988 | -0.0083 | -0.2833 | -0.1014 | -0.463 |
| 2024 | 0.5184 | 0.0358 | -0.3171 | -0.0563 | -0.0977 |
| 2025 | 0.7408 | 0.0646 | -0.2085 | -0.1108 | 0.0761 |
| 2026 | 0.4609 | 0.0502 | -0.1759 | -0.0847 | -0.0546 |
get_factor_correlations
Calculates factor correlations between each factor. This is useful to understand how correlated each factor is to each other. This is based off the Fama and French 5 Factor model which includes:
- Market Risk Premium (Mkt-RF): Represents the additional return that investors expect to earn for taking on the risk of investing in the overall market as opposed to a risk-free asset.
- Size Premium (SMB): Reflects the historical excess return of small-cap stocks over large-cap stocks.
- Value Premium (HML): Captures the historical excess return of value stocks over growth stocks.
- Profitability (RMW): Measures the historical excess return of high profitability stocks over low profitability stocks.
- Investment (CMA): Quantifies the historical excess return of low investment stocks over high investment stocks.
Optionally, it is also possible to see the correlation between the risk-free rate and each factor.
Also known as: factor model correlations.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- factors_to_calculate (list of str, optional): List of factors to calculate scores and residuals for. Defaults to [“Mkt-RF”, “SMB”, “HML”, “RMW”, “CMA”].
- exclude_risk_free (bool, optional): Whether to exclude the risk-free rate from the results. Defaults to True.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
Returns:
pd.DataFrame: Factor Correlations. One correlation matrix per period, stacked into a Multi Index of (period, factor) rows with the factors as the columns and restricted to the Toolkit’s date range.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY", start_date="2023-01-01")
toolkit.performance.get_factor_correlations()
Which returns:
| Mkt-RF | SMB | HML | RMW | CMA | |
|---|---|---|---|---|---|
| (2026, ‘Mkt-RF’) | 1 | 0.1702 | -0.4054 | -0.5902 | -0.4198 |
| (2026, ‘SMB’) | 0.1702 | 1 | 0.2113 | -0.1127 | 0.2437 |
| (2026, ‘HML’) | -0.4054 | 0.2113 | 1 | 0.3432 | 0.7051 |
| (2026, ‘RMW’) | -0.5902 | -0.1127 | 0.3432 | 1 | 0.4182 |
| (2026, ‘CMA’) | -0.4198 | 0.2437 | 0.7051 | 0.4182 | 1 |
get_fama_and_french_model
Calculate Fama and French 5 Factor model scores and residuals for a set of financial assets.
The Fama and French 5 Factor model is a widely used financial model that helps estimate the expected return of financial assets, such as stocks or portfolios, based on five key factors:
- Market Risk Premium (Mkt-RF): Represents the additional return that investors expect to earn for taking on the risk of investing in the overall market as opposed to a risk-free asset.
- Size Premium (SMB): Reflects the historical excess return of small-cap stocks over large-cap stocks.
- Value Premium (HML): Captures the historical excess return of value stocks over growth stocks.
- Profitability (RMW): Measures the historical excess return of high profitability stocks over low profitability stocks.
- Investment (CMA): Quantifies the historical excess return of low investment stocks over high investment stocks.
The model can perform both a Simple Linear Regression on each factor as well as a Multi Linear Regression which includes all factors. Generally, a multi linear regression is applied but if you wish to see individual R-squared values for each factor you can select the simple linear regression method.
The model performs a Linear Regression on each factor and defines the regression parameters and residuals for each asset over time based on its exposure to these factors.
The regression formula is as follows for the Multi Linear Regression:
\[\text{Excess Return} = \text{Intercept} + \text{Beta1} \cdot \text{Mkt-RF} + \text{Beta2} \cdot \text{SMB} + \text{Beta3} \cdot \text{HML} + \text{Beta4} \cdot \text{RMW} + \text{Beta5} \cdot \text{CMA} + \text{Residuals}\]And the following for the Simple Linear Regression:
- Excess Return = Intercept + Slope * Factor Value + Residuals
So for a given factor, it should hold that the Excess Return equals the entire regression. Note that in this calculation the Excess Return refers to the Asset Return minus the Risk Free Rate as reported in the Fama and French dataset and will not be the same as the defined Excess Return in the historical data given that this is based on the Risk Free Rate defined in the initialization.
The regression is estimated on the daily observations falling inside each period, so its Intercept, Slope and Residuals are all on a daily scale. The Factor Value and Residuals columns reported by the Simple Linear Regression therefore describe the last daily observation within the period, which is the only reading for which the identity above holds - they are not period-aggregated quantities.
What is relevant to look at is the influence these factors have on each stock and how much each factor explains the stock return. E.g. you will generally see a pretty high influence (Beta or Slope) for the Market Risk Premium (Mkt-RF) factor as this is the main factor that explains the stock return (as also prevalent in the CAPM). The other factors can fluctuate greatly between stocks depending on which stocks you look at.
Also known as: Fama-French model, three-factor model, five-factor model, FF3, FF5.
Args:
- period (str, optional): The period for the calculation (e.g., “weekly”, “monthly”, “quarterly”, “yearly”). Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- method (str, optional): The regression method to use for the calculation. Defaults to ‘multi’.
- factors_to_calculate (list of str, optional): List of factors to calculate scores and residuals for. Defaults to [“Mkt-RF”, “SMB”, “HML”, “RMW”, “CMA”].
- include_daily_residuals (bool, optional): Whether to also return the pointwise (daily) regression residuals as a second DataFrame. Defaults to False.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratio values. Defaults to False.
- lag (int or list of int, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
- show_columns (list of str, optional): Restrict the result to these top level columns. Defaults to None, which returns every column.
Returns:
pd.DataFrame: Fama and French 5 Factor model scores for the specified assets, with a
Multi Index of (ticker, parameter) as the columns and one row per period. When
include_daily_residuals is True a tuple of (scores, residuals) is returned instead.
Notes:
- The dataset from Fama and French is not always fully up to date. Therefore, some periods could be excluded.
- Daily Fama and French results is not an option as it would attempt to do a linear regression on a single data point which will not give any meaningful results.
- The method retrieves historical data and calculates regression parameters and residuals for each asset.
- The risk-free rate is typically represented by the return of a risk-free investment, such as a Treasury bond. In this case, the Risk Free Rate from the Fama and French dataset is used.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
# Calculate Fama and French 5 Factor model scores
toolkit.performance.get_fama_and_french_model()["AAPL"]
get_carhart_four_factor_model
Calculate Carhart Four Factor model scores for a set of financial assets.
The Carhart Four Factor model extends the Fama and French Three Factor model with a momentum factor, based on the observation that stocks with high prior returns (winners) tend to keep outperforming stocks with low prior returns (losers) over the medium term:
- Market Risk Premium (Mkt-RF): The excess return of the market over the risk-free rate.
- Size Premium (SMB): The historical excess return of small-cap stocks over large-cap stocks.
- Value Premium (HML): The historical excess return of value stocks over growth stocks.
- Momentum (MOM): The historical excess return of prior winner stocks over prior loser stocks.
The model performs a Multi Linear Regression on all four factors and defines the regression parameters for each asset over time based on its exposure to these factors:
- Excess Return = Intercept + Beta1 * Mkt-RF + Beta2 * SMB + Beta3 * HML + Beta4 * MOM + Residuals
For more information about the method, see the following paper:
- Carhart, M.M. (1997). “On Persistence in Mutual Fund Performance.” The Journal of Finance, 52(1), 57-82.
Also known as: Carhart model, four-factor model, momentum-augmented Fama-French model.
Args:
- period (str, optional): The period for the calculation (e.g., “weekly”, “monthly”, “quarterly”, “yearly”). Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratio values. Defaults to False.
- lag (int or list of int, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
- show_columns (list of str, optional): Restrict the result to these top level columns. Defaults to None, which returns every column.
Returns:
pd.DataFrame: Carhart Four Factor model scores for the specified assets, with a Multi Index of (ticker, parameter) as the columns and one row per period.
Notes:
- The dataset from Ken French is not always fully up to date. Therefore, some periods could be excluded.
- Daily Carhart results is not an option as it would attempt to do a linear regression on a single data point which will not give any meaningful results.
- The factors come from the Fama and French three factor file rather than the five factor file
used by
get_fama_and_french_model. The two files agree on Mkt-RF, HML and RF but not on SMB: the five factor SMB averages three separate size legs, while Carhart (1997) extends the three factor model and therefore requires the three factor SMB. - The risk-free rate is the Risk Free Rate reported in the Fama and French dataset (used here, rather than the Toolkit’s own risk-free rate, to stay consistent with the momentum factor’s construction).
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AMZN", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_carhart_four_factor_model(period="quarterly")["AMZN"]
get_alpha
Alpha, in a general sense, represents the excess return an investment generates relative to a benchmark or a risk-adjusted return. It can be positive (indicating the investment outperformed the benchmark) or negative (indicating underperformance).
The formula is as follows:
\[\text{Alpha} = \text{Asset's Actual Return} - \text{Benchmark's Actual Return}\]See definition: https://en.wikipedia.org/wiki/Alpha_(finance)
Also known as: excess return, outperformance, active return.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rolling (int, optional): The rolling window size to use for the calculation. If set,
Alpha is calculated as the rolling mean excess return over this many periods across
the full return history instead of per
period. Defaults to None. - rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Alpha values.
Notes:
- The method retrieves historical data and calculates the Alpha for each asset in the Toolkit instance.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_alpha()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | 0.0678 | 0.2272 |
| 2022 | -0.0735 | -0.4555 |
| 2023 | 0.2389 | 0.7743 |
| 2024 | 0.0677 | 0.3922 |
| 2025 | -0.0779 | -0.0499 |
| 2026 | 0.0431 | -0.2173 |
get_jensens_alpha
Calculate Jensen’s Alpha, a measure of an asset’s performance relative to its expected return based on the Capital Asset Pricing Model (CAPM).
Jensen’s Alpha is used to assess whether an investment has outperformed or underperformed its expected return given its systematic risk, as represented by the asset’s Beta.
The formula is as follows:
\[\text{Jensen's Alpha} = \text{Asset's Actual Return} - \left[\text{Risk-Free Rate} + \text{Beta} \cdot (\text{Benchmark Return} - \text{Risk-Free Rate})\right]\]See definition: https://en.wikipedia.org/wiki/Jensen%27s_alpha
Also known as: Jensen alpha, risk-adjusted excess return.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rolling (int, optional): The rolling window size to use for the Beta component of the
calculation. If set, Beta is estimated over a rolling window of this many periods across
the full return history instead of per
period. Defaults to None. - rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Jensen’s Alpha values.
Notes:
- Daily Jensen’s Alpha is not an option as the standard deviation for 1 day is close to zero. Therefore, it does not give any useful insights.
- The method retrieves historical data and calculates the CAPM for each asset in the Toolkit instance.
- The risk-free rate is often represented by the return of a risk-free investment, such as a Treasury bond.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_jensens_alpha()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | -0.0112 | 0.0062 |
| 2022 | -0.0037 | -0.2837 |
| 2023 | 0.2185 | 0.5267 |
| 2024 | 0.0741 | 0.1328 |
| 2025 | -0.1082 | -0.1999 |
| 2026 | 0.0531 | -0.2615 |
get_treynor_ratio
The Treynor Ratio, also known as Treynor’s Measure or the Reward-to-Variability Ratio, is a financial metric used to assess the risk-adjusted performance of an investment portfolio or asset. It measures the excess return generated by the portfolio per unit of systematic or market risk, often represented by Beta. The Treynor Ratio is a valuable tool for evaluating the performance of investments in relation to their market risk exposure.
The formula is as follows:
\[\text{Treynor Ratio} = (\text{Portfolio's Return} - \text{Risk-Free Rate}) / \text{Portfolio Beta}\]See definition: https://en.wikipedia.org/wiki/Treynor_ratio
Also known as: reward-to-volatility ratio.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rolling (int, optional): The rolling window size to use for the Beta component of the
calculation. If set, Beta is estimated over a rolling window of this many periods across
the full return history instead of per
period. Defaults to None. - rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Treynor Ratio values.
Notes:
- Daily Treynor Ratio is not an option as the standard deviation for 1 day is close to zero. Therefore, it does not give any useful insights.
- The method retrieves historical data and calculates the TR for each asset in the Toolkit instance.
- The risk-free rate is often represented by the return of a risk-free investment, such as a Treasury bond.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_treynor_ratio()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | 0.2468 | 0.2586 |
| 2022 | -0.2364 | -0.3971 |
| 2023 | 0.4028 | 0.4422 |
| 2024 | 0.2641 | 0.243 |
| 2025 | 0.0352 | 0.0323 |
| 2026 | 0.1146 | -0.0879 |
get_sharpe_ratio
Calculate the Sharpe ratio, a measure of risk-adjusted return that evaluates the excess return of an investment portfolio or asset per unit of risk taken.
The Sharpe ratio is calculated as the difference between the expected return of the asset or portfolio and the risk-free rate of return, divided by the standard deviation of the asset or portfolio’s excess return. It quantifies the amount of return generated for each unit of risk assumed, providing insights into the investment’s performance relative to the risk taken.
The formula is as follows:
\[\text{Sharpe Ratio} = \text{Excess Return} / \text{Excess Standard Deviation}\]By default one Sharpe ratio is reported per period, computed from the daily excess returns falling inside that period. For a given period, for example monthly, this translates into the following:
For a rolling period, period instead sets the frequency of the returns themselves and the ratio is computed over a rolling window of rolling such returns:
Note that this is explicitly already subtracts the Risk Free Rate.
The result is not annualized: it is a per-observation Sharpe ratio, so a value computed from daily returns is roughly SQRT(252) smaller than the annualized figure usually quoted in the literature (SQRT(52), SQRT(12) and SQRT(4) for weekly, monthly and quarterly returns respectively). Multiply by that factor before comparing against published annualized Sharpe ratios.
The plain Sharpe ratio only looks at the mean and standard deviation of returns, implicitly assuming Gaussian, i.i.d. returns and ignoring how much uncertainty surrounds the estimate itself. The method parameter selects one of three corrections for that, each keeping the same excess returns and therefore the same underlying Sharpe ratio as its starting point:
"adjusted"- the Adjusted Sharpe Ratio (ASR, Pezier & White, 2006) penalizes (or rewards) the Sharpe ratio for negative skewness and excess kurtosis using a Cornish-Fisher-style expansion, so that two strategies with the same Sharpe ratio but different tail shapes are no longer scored identically:- ASR = SR * [1 + (S / 6) * SR − ((K − 3) / 24) * SR^2]
"probabilistic"- the Probabilistic Sharpe Ratio (PSR) is the probability that the true (population) Sharpe ratio exceedsbenchmark_sharpe_ratio, folding the skewness and (non-excess) kurtosis of the underlying returns into the standard error of the Sharpe ratio so that a short, lumpy sample no longer looks more convincing than it is:- PSR(SR) = Φ( (SR̂ − SR) · sqrt(n − 1) / sqrt(1 − γ₃·SR̂ + ((γ₄ − 1) / 4)·SR̂²) )
"deflated"- the Deflated Sharpe Ratio (DSR) is the Probabilistic Sharpe Ratio corrected for the fact that a reported Sharpe ratio is often the best of many strategy variations, parameter combinations, or lookback windows tried during a backtest (multiple testing / selection bias / “backtest overfitting”). It estimates the Sharpe ratio one would expect to observe purely by chance as the maximum ofn_trialsindependent trials under the null hypothesis of no skill, and uses that expected maximum as the benchmark SR* in the Probabilistic Sharpe Ratio formula instead of a naive benchmark such as 0:
Where SR̂ is the observed Sharpe ratio, S (γ₃) is the skewness and K (γ₄) the non-excess (raw) kurtosis of the same returns, n is the number of return observations, N is n_trials, Var[SR_trials] is the variance of the Sharpe ratios observed across those N trials, γ ≈ 0.5772 is the Euler-Mascheroni constant and Φ is the standard normal CDF. Since DSR = PSR(SR*), it is always less than or equal to the Probabilistic Sharpe Ratio computed against a benchmark of 0.
This codebase does not track “N literal strategy trials” - there is no record of how many parameter combinations were tried before arriving at the current Toolkit configuration. As a documented approximation, Var[SR_trials] is estimated from the variance of an auxiliary rolling Sharpe ratio series (see get_rolling_sharpe_ratio) computed over a trials_window-sized window across the full return history, and n_trials defaults to the number of valid (non-NaN) values in that same rolling series. This treats each rolling window as if it were one “trial” - a reasonable proxy for how dispersed the Sharpe ratio could plausibly have been under different choices, but not a substitute for passing the actual number of variations tried (via n_trials) when that is known, since the quality of the correction depends directly on it.
See definition: https://en.wikipedia.org/wiki/Sharpe_ratio
Also known as: risk-adjusted return, reward-to-variability ratio. The variants are also known as the Pezier and White Adjusted Sharpe Ratio (ASR), the Sharpe ratio significance probability (PSR) and the backtest overfitting or selection-bias-adjusted Sharpe ratio (DSR).
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rolling (int, optional): The rolling period to use for the calculation. If you select period = ‘monthly’ and set rolling to 12 you obtain the rolling 12-month Sharpe Ratio.
- method (str, optional): Which Sharpe ratio to calculate, one of “standard”, “adjusted”, “probabilistic” or “deflated”, as described above. Defaults to “standard”.
- benchmark_sharpe_ratio (float, optional): The hypothesized or benchmark Sharpe ratio (SR*) to test the observed Sharpe ratio against. Only used when method=”probabilistic”. Defaults to 0.0, i.e. testing whether the strategy has any skill at all above doing nothing.
- trials_window (int, optional): The window size (in units of
period) used for the auxiliary rolling Sharpe ratio series that approximatesVar[SR_trials]and the defaultn_trials, see above. Only used when method=”deflated”. Defaults to None, which uses half of the available return history so that enough overlapping windows exist regardless ofperiodor date range. - n_trials (int, optional): The number of independent (or effectively independent) strategy variations, parameter combinations, or lookback windows tried before arriving at the reported Sharpe ratio. Only used when method=”deflated”. Defaults to None, which falls back to the number of valid values in the auxiliary rolling Sharpe ratio series described above. Pass this explicitly whenever the actual number of trials is known.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Sharpe ratio values. For method=”probabilistic” and method=”deflated” these are probabilities between 0 and 1 rather than ratios.
Notes:
- Daily Sharpe Ratio is not an option as the standard deviation for 1 day is close to zero. Therefore, it does not give any useful insights.
- The method retrieves historical data and calculates the Sharpe ratio for each asset in the Toolkit instance.
- The risk-free rate is often represented by the return of a risk-free investment, such as a Treasury bond.
- The “adjusted”, “probabilistic” and “deflated” variants use the non-excess (raw) kurtosis
convention, i.e. a Normal distribution has a kurtosis of 3, not 0. Internally this calls
risk_model.get_kurtosis(..., fisher=False). - If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_sharpe_ratio()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | 0.1277 | 0.1334 |
| 2022 | -0.0482 | -0.0812 |
| 2023 | 0.1189 | 0.095 |
| 2024 | 0.07 | 0.0637 |
| 2025 | 0.0188 | 0.0263 |
| 2026 | 0.0475 | -0.0604 |
And, asking for the probability that these Sharpe ratios are genuine instead:
toolkit.performance.get_sharpe_ratio(method="probabilistic")
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | 0.8922 | 0.9022 |
| 2022 | 0.225 | 0.0998 |
| 2023 | 0.9684 | 0.9323 |
| 2024 | 0.8693 | 0.8496 |
| 2025 | 0.618 | 0.6618 |
| 2026 | 0.7167 | 0.2264 |
get_sortino_ratio
The Sortino Ratio is a financial metric used to assess the risk-adjusted performance of an investment portfolio or asset by considering only the downside risk. It measures the excess return generated by the portfolio per unit of downside risk, specifically, the standard deviation of negative returns. The Sortino Ratio is particularly useful for investors who are primarily concerned with minimizing the downside risk of their investments.
The formula is as follows:
\[\text{Sortino Ratio} = \text{Excess Return} / \text{Downside Deviation}\] \[\text{Downside Deviation} = \sqrt{(1 / N) \cdot \operatorname{SUM}(\min(\text{Excess Return},\; 0) ^{2})}\]Where N is the total number of observations, not just the negative ones, following Sortino & Price (1994). By default one Sortino ratio is reported per period, computed from the daily excess returns falling inside that period. For a given period, for example monthly, this translates into the following:
For a rolling period, period instead sets the frequency of the returns themselves and the ratio is computed over a rolling window of rolling such returns:
Note that this is explicitly already subtracts the Risk Free Rate.
As with the Sharpe Ratio, the result is not annualized: it is a per-observation ratio, so multiply by SQRT(252), SQRT(52), SQRT(12) or SQRT(4) for daily, weekly, monthly or quarterly returns respectively before comparing against published annualized figures.
See definition: https://en.wikipedia.org/wiki/Sortino_ratio
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rolling (int, optional): The rolling window size to use for the calculation. If set,
the Sortino ratio is calculated over a rolling window of this many periods across the
full return history instead of per
period. Defaults to None. - rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Sortino ratio values.
Notes:
- Daily Sortino Ratio is not an option as the standard deviation for 1 day is close to zero. Therefore, it does not give any useful insights.
- The method retrieves historical data and calculates the Sortino ratio for each asset in the Toolkit instance.
- The risk-free rate is often represented by the return of a risk-free investment, such as a Treasury bond.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_sortino_ratio()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | 0.197 | 0.2049 |
| 2022 | -0.0675 | -0.1069 |
| 2023 | 0.1839 | 0.1462 |
| 2024 | 0.1071 | 0.1044 |
| 2025 | 0.0283 | 0.0391 |
| 2026 | 0.0665 | -0.0789 |
get_ulcer_performance_index
Calculate the Ulcer Performance Index (UPI), alternatively called Martin ratio, a measure of risk-adjusted return that evaluates the excess return of an investment portfolio or asset per unit of risk taken.
It can be used to compare volatilities in different stocks or show stocks go into Ulcer territory. Similar to the Sharpe Ratio, a higher UPI is better than a lower one (since investors prefer more return for less risk).
Also known as: UPI, Martin ratio.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rolling (int): The rolling period to use to calculate the Ulcer Index. Defaults to 14.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Ulcer Performance Index values.
Notes:
- The method retrieves historical data and calculates the UPI for each asset in the Toolkit instance.
- The risk-free rate is often represented by the return of a risk-free investment, such as a Treasury bond.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_ulcer_performance_index()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | -0.4626 | -0.2002 |
| 2022 | -4.5193 | -5.0182 |
| 2023 | 13.6486 | 11.6618 |
| 2024 | 7.6983 | 6.3795 |
| 2025 | 0.9945 | 0.7159 |
| 2026 | 2.2021 | -3.5198 |
get_calmar_ratio
Calculate the Calmar Ratio of an investment portfolio or asset’s returns.
The Calmar Ratio is a risk-adjusted return metric that divides the (annualized) return of an investment portfolio or asset by its Maximum Drawdown, providing insight into the return achieved per unit of the worst historical loss of value.
The formula is as follows:
\[\text{Calmar Ratio} = \text{Return} / | \text{Maximum Drawdown} |\]See definition: https://en.wikipedia.org/wiki/Calmar_ratio
Also known as: Drawdown ratio.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- within_period (bool, optional): Whether to calculate the Maximum Drawdown within the specified period or for the entire period. Thus whether to look at the Maximum Drawdown within a specific year (if period = ‘yearly’) or look at the entirety of all years. Defaults to True.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Calmar Ratio values.
Notes:
- The method retrieves historical data and calculates the Calmar Ratio for each asset in the Toolkit instance.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_calmar_ratio()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | 1.8052 | 1.3727 |
| 2022 | -0.8734 | -0.8942 |
| 2023 | 3.1929 | 3.1074 |
| 2024 | 1.9404 | 1.461 |
| 2025 | 0.2834 | 0.2356 |
| 2026 | 1.0648 | -0.5212 |
get_sterling_ratio
Calculate the Sterling Ratio of an investment portfolio or asset’s returns.
The Sterling Ratio is a risk-adjusted return metric that divides the (annualized) return of an investment portfolio or asset by its Average Drawdown plus a fixed adjustment (conventionally 10%), providing insight into the return achieved relative to the typical depth of its drawdowns rather than only the single worst one (as with the Calmar Ratio).
The formula is as follows:
\[\text{Sterling Ratio} = \text{Return} / (| \text{Average Drawdown} | + \text{Adjustment})\]Also known as: Sterling-Calmar ratio.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- within_period (bool, optional): Whether to calculate the Average Drawdown within the specified period or for the entire period. Thus whether to look at the Average Drawdown within a specific year (if period = ‘yearly’) or look at the entirety of all years. Defaults to True.
- adjustment (float, optional): The fixed adjustment added to the Average Drawdown, conventionally 0.1 (10%). Defaults to 0.1.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Sterling Ratio values.
Notes:
- The method retrieves historical data and calculates the Sterling Ratio for each asset in the Toolkit instance.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_sterling_ratio()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | 2.0094 | 1.7258 |
| 2022 | -1.074 | -1.4667 |
| 2023 | 3.2891 | 4.193 |
| 2024 | 1.9286 | 2.1544 |
| 2025 | 0.4371 | 0.3785 |
| 2026 | 0.886 | -0.6097 |
get_burke_ratio
Calculate the Burke Ratio of an investment portfolio or asset’s returns.
The Burke Ratio is a risk-adjusted return metric that divides the excess return (return minus the risk-free rate) of an investment portfolio or asset by the square root of the sum of its squared drawdowns, penalizing both the frequency and depth of drawdowns more heavily than the Calmar or Sterling Ratios.
The formula is as follows:
\[\text{Burke Ratio} = (\text{Return} - \text{Risk-Free Rate}) / \sqrt{\operatorname{SUM}(\text{Drawdowns} ^{2})}\]Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- within_period (bool, optional): Whether to calculate the drawdowns within the specified period or for the entire period. Thus whether to look at the drawdowns within a specific year (if period = ‘yearly’) or look at the entirety of all years. Defaults to True.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Burke Ratio values.
Notes:
- The method retrieves historical data and calculates the Burke Ratio for each asset in the Toolkit instance.
- The risk-free rate is often represented by the return of a risk-free investment, such as a Treasury bond.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_burke_ratio()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | 0.2606 | 0.1513 |
| 2022 | -0.1172 | -0.1172 |
| 2023 | 0.502 | 0.4155 |
| 2024 | 0.2519 | 0.1765 |
| 2025 | 0.0246 | 0.0195 |
| 2026 | 0.1417 | -0.1284 |
get_m2_ratio
The M2 Ratio, also known as the Modigliani-Modigliani Measure, is a financial metric used to evaluate the risk-adjusted performance of an investment portfolio or strategy. It assesses the excess return generated by the portfolio relative to a risk-free investment, taking into account the portfolio’s volatility or risk. The M2 Ratio helps investors and portfolio managers determine whether the portfolio is delivering returns that justify its level of risk.
The formula is as follows:
\[M_{2} \text{Ratio} = \text{Risk-Free Rate} + \left[(\text{Portfolio's Return} - \text{Risk-Free Rate}) / \text{Portfolio Standard Deviation}\right] \cdot \text{Benchmark Standard Deviation}\]This rescales the (dimensionless) Sharpe ratio back into return-space by asking what return the portfolio would have earned had it been leveraged or de-leveraged, via risk-free borrowing or lending, to match the benchmark’s volatility exactly – producing a number directly comparable to the benchmark’s actual return. Requires a benchmark_ticker to be set on the Toolkit instance, since the benchmark’s standard deviation is part of the formula.
See definition: https://en.wikipedia.org/wiki/Modigliani_risk-adjusted_performance
Also known as: Modigliani-Modigliani measure, M2, risk-adjusted performance.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rolling (int, optional): The rolling window size to use for the calculation. If set,
the M2 ratio is calculated over a rolling window of this many periods across the full
return history instead of per
period. Defaults to None. - rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: M2 ratio values.
Notes:
- Daily M2 is not an option as the standard deviation for 1 day is close to zero. Therefore, it does not give any useful insights.
- The method retrieves historical data and calculates the M2 for each asset in the Toolkit instance.
- The risk-free rate is often represented by the return of a risk-free investment, such as a Treasury bond.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_m2_ratio()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | 0.0065 | 0.0112 |
| 2022 | -0.1669 | -0.2118 |
| 2023 | 0.3293 | 0.2753 |
| 2024 | 0.1905 | 0.1604 |
| 2025 | 0.0709 | 0.0637 |
| 2026 | 0.0919 | -0.0461 |
get_tracking_error
Tracking Error is a financial metric that quantifies the volatility or dispersion of the difference between the returns of an investment portfolio or asset and the returns of a benchmark index. It measures how closely the portfolio tracks its benchmark and provides insights into the consistency of the portfolio’s performance relative to the benchmark. A higher Tracking Error indicates greater divergence from the benchmark, while a lower Tracking Error suggests that the portfolio closely follows the benchmark.
The formula is as follows:
\[\text{Tracking Error} (\text{TE}) = \text{Standard Deviation of} (\text{Portfolio Returns} - \text{Benchmark Returns})\]See definition: https://en.wikipedia.org/wiki/Tracking_error
Also known as: active risk, benchmark deviation.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rolling (int, optional): The rolling window size to use for the calculation. If set,
Tracking Error is calculated over a rolling window of this many periods across the
full return history instead of per
period. Defaults to None. - rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Tracking error values.
Notes:
- Daily Tracking Error is not an option as the standard deviation for 1 day is close to zero. Therefore, it does not give any useful insights.
- The method retrieves historical data and calculates the TE for each asset in the Toolkit instance.
- The risk-free rate is often represented by the return of a risk-free investment, such as a Treasury bond.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_tracking_error()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | 0.0118 | 0.0317 |
| 2022 | 0.0115 | 0.0344 |
| 2023 | 0.009 | 0.0304 |
| 2024 | 0.0121 | 0.0369 |
| 2025 | 0.0139 | 0.0328 |
| 2026 | 0.0154 | 0.0226 |
get_information_ratio
The Information Ratio (IR), also known as the Information Coefficient, is a financial metric that assesses the risk-adjusted performance of a portfolio or investment strategy relative to a benchmark index. It quantifies how much excess return the portfolio generates for each unit of tracking error (volatility of tracking error). The Information Ratio is commonly used by portfolio managers, financial analysts, and investors to evaluate the skill of a portfolio manager in generating returns beyond what would be expected based on the risk taken.
- IR > 0: A positive Information Ratio indicates that the portfolio has generated excess returns compared to the benchmark, suggesting that the portfolio manager has added value.
- IR = 0: An Information Ratio of zero implies that the portfolio’s excess return is in line with the benchmark, meaning the portfolio manager has not added or lost value relative to the benchmark.
- IR < 0: A negative Information Ratio suggests that the portfolio has underperformed the benchmark, potentially indicating that the portfolio manager has detracted value.
The formula is as follows:
\[\text{Information Ratio} (\text{IR}) = (\text{Portfolio's Excess Return} - \text{Benchmark's Excess Return}) / \text{Tracking Error}\]See definition: https://en.wikipedia.org/wiki/Information_ratio
Also known as: active return per risk.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rolling (int, optional): The rolling window size to use for the calculation. If set,
the Information Ratio is calculated over a rolling window of this many periods across
the full return history instead of per
period. Defaults to None. - rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Information ratio values.
Notes:
- Daily Information Ratio is not an option as the standard deviation for 1 day is close to zero. Therefore, it does not give any useful insights.
- The method retrieves historical data and calculates the IR for each asset in the Toolkit instance.
- The risk-free rate is often represented by the return of a risk-free investment, such as a Treasury bond.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_information_ratio()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | 0.0253 | 0.0381 |
| 2022 | -0.0212 | -0.0739 |
| 2023 | 0.0833 | 0.0817 |
| 2024 | 0.0231 | 0.0499 |
| 2025 | -0.0106 | 0.0164 |
| 2026 | 0.0269 | -0.0641 |
get_upside_capture_ratio
Calculate the Upside Capture Ratio of an investment portfolio or asset’s returns.
The Upside Capture Ratio measures how well an investment portfolio or asset performs relative to a benchmark during periods in which the benchmark’s return is positive. A ratio above 1 (or 100%) indicates the asset captured more of the benchmark’s gains than the benchmark itself.
The formula is as follows:
\[\text{Upside Capture Ratio} = \text{Average Return in Up Periods} / \text{Average Benchmark Return in Up Periods}\]Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Upside Capture Ratio values.
Notes:
- The method retrieves historical data and calculates the Upside Capture Ratio for each asset in the Toolkit instance.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_upside_capture_ratio()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | 1.3754 | 2.1079 |
| 2022 | 1.3044 | 1.7261 |
| 2023 | 1.1783 | 2.3099 |
| 2024 | 1.1158 | 2.5976 |
| 2025 | 1.0162 | 2.2065 |
| 2026 | 0.766 | 1.593 |
get_downside_capture_ratio
Calculate the Downside Capture Ratio of an investment portfolio or asset’s returns.
The Downside Capture Ratio measures how well an investment portfolio or asset performs relative to a benchmark during periods in which the benchmark’s return is negative. A ratio below 1 (or 100%) indicates the asset lost less than the benchmark during those periods.
The formula is as follows:
\[\text{Downside Capture Ratio} = \text{Average Return in Down Periods} / \text{Average Benchmark Return in Down Periods}\]Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Downside Capture Ratio values.
Notes:
- The method retrieves historical data and calculates the Downside Capture Ratio for each asset in the Toolkit instance.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_downside_capture_ratio()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | 1.4016 | 2.0639 |
| 2022 | 1.3043 | 2.0238 |
| 2023 | 0.9486 | 1.8386 |
| 2024 | 1.0337 | 2.4414 |
| 2025 | 1.0842 | 2.2603 |
| 2026 | 0.5691 | 2.2236 |
get_win_rate
Calculate the Win Rate of an investment portfolio or asset’s returns.
The Win Rate is the percentage of periods in which the asset’s return exceeds the benchmark’s return.
Also known as: batting average.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Win Rate values.
Notes:
- The method retrieves historical data and calculates the Win Rate for each asset in the Toolkit instance.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_win_rate()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | 0.4921 | 0.5 |
| 2022 | 0.4821 | 0.498 |
| 2023 | 0.576 | 0.532 |
| 2024 | 0.504 | 0.4683 |
| 2025 | 0.472 | 0.468 |
| 2026 | 0.504 | 0.472 |
get_kappa_ratio
Calculate the Kappa Ratio of an investment portfolio or asset’s returns.
The Kappa Ratio is a generalization of the Sortino Ratio that penalizes downside risk using a higher-order lower partial moment. The Sortino Ratio is the special case of the Kappa Ratio with order=2.
Note that this already subtracts the Risk Free Rate.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- order (int, optional): The order of the lower partial moment used in the denominator. Defaults to 3.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Kappa Ratio values.
Notes:
- Daily Kappa Ratio is not an option as the standard deviation for 1 day is close to zero. Therefore, it does not give any useful insights.
- The method retrieves historical data and calculates the Kappa Ratio for each asset in the Toolkit instance.
- The risk-free rate is often represented by the return of a risk-free investment, such as a Treasury bond.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_kappa_ratio()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2021 | 0.1414 | 0.1382 |
| 2022 | -0.052 | -0.0816 |
| 2023 | 0.1284 | 0.1026 |
| 2024 | 0.0767 | 0.0749 |
| 2025 | 0.0186 | 0.0275 |
| 2026 | 0.0441 | -0.0538 |
get_omega_ratio
Calculate the Omega Ratio of an investment portfolio or asset’s returns.
The Omega Ratio is a risk-return measure that divides the sum of gains above a minimum acceptable return (MAR) by the sum of losses below it, capturing the full shape of the return distribution rather than only its first two moments (unlike the Sharpe Ratio).
The formula is as follows:
\[\text{Omega Ratio} = \operatorname{SUM}(\text{Gains above MAR}) / \operatorname{SUM}(\text{Losses below MAR})\]See definition: https://en.wikipedia.org/wiki/Omega_ratio
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- within_period (bool, optional): Whether to calculate the Omega Ratio within the specified period or for the entire period. Thus whether to look at the Omega Ratio within a specific year (if period = ‘yearly’) or look at the entirety of all years. Defaults to True.
- rolling (int, optional): The rolling window size to use for the calculation. If set, the
Omega Ratio is calculated over a rolling window of this many periods across the full
return history instead of per
period. Defaults to None. - minimum_acceptable_return (float, optional): The minimum acceptable return (MAR) used as the threshold between gains and losses. Defaults to 0.0.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Omega Ratio values.
Notes:
- The method retrieves historical data and calculates the Omega Ratio for each asset in the Toolkit instance.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_omega_ratio()
Which returns:
| AAPL | TSLA | |
|---|---|---|
| 2021 | 1.2354 | 1.1945 |
| 2022 | 0.892 | 0.8129 |
| 2023 | 1.4034 | 1.3043 |
| 2024 | 1.2462 | 1.2098 |
| 2025 | 1.0873 | 1.0871 |
| 2026 | 1.2062 | 0.9358 |
get_gain_to_pain_ratio
Calculate the Gain-to-Pain Ratio of an investment portfolio or asset’s returns.
The Gain-to-Pain Ratio, popularized by Jack Schwager, divides the sum of all returns by the sum of the absolute value of all losses, summarizing the entire return history into a single measure of return earned per unit of pain endured.
The formula is as follows:
\[\text{Gain-to-Pain Ratio} = \operatorname{SUM}(\text{Returns}) / \operatorname{SUM}(| \text{Losses} |)\]Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- within_period (bool, optional): Whether to calculate the Gain-to-Pain Ratio within the specified period or for the entire period. Thus whether to look at the Gain-to-Pain Ratio within a specific year (if period = ‘yearly’) or look at the entirety of all years. Defaults to True.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Gain-to-Pain Ratio values.
Notes:
- The method retrieves historical data and calculates the Gain-to-Pain Ratio for each asset in the Toolkit instance.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_gain_to_pain_ratio()
Which returns:
| AAPL | TSLA | |
|---|---|---|
| 2021 | 0.2354 | 0.1945 |
| 2022 | -0.108 | -0.1871 |
| 2023 | 0.4034 | 0.3043 |
| 2024 | 0.2462 | 0.2098 |
| 2025 | 0.0873 | 0.0871 |
| 2026 | 0.2062 | -0.0642 |
get_compound_growth_rate
This function calculates the Compound Growth Rate (CGR) for different periods: yearly, quarterly, monthly, weekly, and daily.
The CGR is a measure that provides the mean growth rate of an investment over a specified period of time. It is a useful measure for comparing the performance of investments over different time periods or across different asset classes. The CGR is calculated by taking the ratio of the final value to the initial value, raising it to the inverse of the number of periods, and then subtracting one.
The formula is as follows:
\[\text{CGR} = (\text{Final Value} / \text{Initial Value}) ^{1 / \text{Number of Periods}} - 1\]Also known as: CAGR, compound annual growth rate, annualized return.
Args:
- rounding (int, optional): The number of decimals to round the results to. If not provided, the function will use the default rounding value set in the class instance.
Returns:
pd.DataFrame: A DataFrame containing the CGR for each period. The DataFrame has the periods as the index and the CGR values as the column.
Notes:
- When verifying the calculation, note that rounding applies and it could be slightly off because of that This is mostly noticeable when looking at the Compound Daily Growth Rate. Adjust the rounding with the rounding parameter accordingly to get a more precise figure.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_compound_growth_rate()
Which returns:
| AAPL | TSLA | Benchmark | |
|---|---|---|---|
| Compound Annual Growth Rate (CAGR) | 0.1219 | -0.0124 | 0.1158 |
| Compound Quarterly Growth Rate (CQGR) | 0.041 | 0.0124 | 0.0332 |
| Compound Monthly Growth Rate (CMGR) | 0.0123 | 0.005 | 0.0101 |
| Compound Weekly Growth Rate (CWGR) | 0.0029 | 0.0012 | 0.0024 |
| Compound Daily Growth Rate (CDGR) | 0.0006 | 0.0003 | 0.0005 |
get_returns
Calculate the Return of an investment portfolio or asset for a given period based on the daily historical returns.
The period Return is obtained by compounding the daily returns within each period, following the formula:
\[\text{Period Return} = ((1 + \text{Return} 1) \cdot (1 + \text{Return} 2) \cdot ... \cdot (1 + \text{Return} N)) - 1\]If cumulative is set to True, the period returns are compounded further into a cumulative return over time instead. The cumulative return is always rebased to start at 1 at the beginning of the selected date range.
Also known as: periodic return.
Args:
- period (str, optional): The data frequency for returns (weekly, monthly, quarterly, or yearly). Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- cumulative (bool, optional): Whether to return the cumulative return over time instead of the discrete return per period. Defaults to False.
- rounding (int \| None, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the Return values over time. Defaults to False.
- lag (int \| list[int], optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.Series: Return values with time as the index.
Notes:
- The method retrieves the daily historical return data and calculates the Return for
the specified
periodfor each asset in the Toolkit instance. - If
growthis set to True, the method calculates the growth of Return values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AMZN", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_returns(period="yearly")
Which returns:
| Date | AMZN | TSLA | Benchmark |
|---|---|---|---|
| 2021 | 0.0236 | 0.4983 | 0.2701 |
| 2022 | -0.496 | -0.6503 | -0.1949 |
| 2023 | 0.8089 | 1.0174 | 0.2429 |
| 2024 | 0.4449 | 0.6255 | 0.2339 |
| 2025 | 0.0516 | 0.1129 | 0.1638 |
| 2026 | 0.0508 | -0.1254 | 0.0918 |
get_excess_return
Calculate the Excess Return of an investment portfolio or asset for a given period based on the daily historical returns.
The Excess Return is defined as the period Return minus the risk free rate.
If cumulative is set to True, the excess returns are compounded further into a cumulative excess return over time instead. The cumulative excess return is always rebased to start at 1 at the beginning of the selected date range.
Also known as: return minus the risk-free rate.
Args:
- period (str, optional): The data frequency for returns (weekly, monthly, quarterly, or yearly). Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- cumulative (bool, optional): Whether to return the cumulative excess return over time instead of the discrete excess return per period. Defaults to False.
- rounding (int \| None, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the Excess Return values over time. Defaults to False.
- lag (int \| list[int], optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.Series: Excess Return values with time as the index.
Notes:
- The method retrieves the daily historical return data and calculates the Excess Return for
the specified
periodfor each asset in the Toolkit instance. - The risk-free rate is often represented by the return of a risk-free investment, such as a Treasury bond.
- If
growthis set to True, the method calculates the growth of Excess Return values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AMZN", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_excess_return(period="yearly")
Which returns:
| Date | AMZN | TSLA | Benchmark |
|---|---|---|---|
| 2021 | 0.0085 | 0.4832 | 0.255 |
| 2022 | -0.5348 | -0.6891 | -0.2337 |
| 2023 | 0.7702 | 0.9787 | 0.2042 |
| 2024 | 0.3992 | 0.5798 | 0.1882 |
| 2025 | 0.01 | 0.0713 | 0.1222 |
| 2026 | 0.0059 | -0.1703 | 0.0469 |
get_correlation_matrix
Calculate the full pairwise Correlation Matrix across all assets (and the benchmark) in the Toolkit instance, based on the returns at the frequency given by period.
Unlike get_beta, which relates a single asset to the benchmark, this computes the correlation between every pair of assets at once. This is a prerequisite for portfolio variance calculations and any mean-variance optimization work.
Args:
- period (str, optional): The data frequency for returns (weekly, monthly, quarterly, or yearly). Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rounding (int \| None, optional): The number of decimals to round the results to. Defaults to 4.
Returns:
pd.DataFrame: The N x N Correlation Matrix, with assets as both the index and the columns.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AMZN", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_correlation_matrix()
Which returns:
| AMZN | TSLA | Benchmark | |
|---|---|---|---|
| AMZN | 1 | 0.935 | 0.7751 |
| TSLA | 0.935 | 1 | 0.8982 |
| Benchmark | 0.7751 | 0.8982 | 1 |
get_covariance_matrix
Calculate the full pairwise Covariance Matrix across all assets (and the benchmark) in the Toolkit instance, based on the returns at the frequency given by period.
Unlike get_covariance, which relates a single asset to the benchmark, this computes the covariance between every pair of assets at once. This is a prerequisite for portfolio variance calculations and any mean-variance optimization work.
Args:
- period (str, optional): The data frequency for returns (weekly, monthly, quarterly, or yearly). Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rounding (int \| None, optional): The number of decimals to round the results to. Defaults to 4.
Returns:
pd.DataFrame: The N x N Covariance Matrix, with assets as both the index and the columns.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AMZN", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_covariance_matrix()
Which returns:
| AMZN | TSLA | Benchmark | |
|---|---|---|---|
| AMZN | 0.1944 | 0.2418 | 0.0592 |
| TSLA | 0.2418 | 0.344 | 0.0913 |
| Benchmark | 0.0592 | 0.0913 | 0.0301 |
get_appraisal_ratio
Calculate the Appraisal Ratio, i.e. Jensen’s Alpha divided by the idiosyncratic (residual, unsystematic) standard deviation left over from the CAPM regression that produced that Alpha.
Jensen’s Alpha (see get_jensens_alpha) measures how much return a manager generated above what CAPM would predict given the asset’s Beta. However, a large Alpha achieved with wildly noisy, unpredictable residual returns is far less attractive than the same Alpha achieved consistently. The Appraisal Ratio normalizes Alpha by that noise (the “specific risk” not explained by market exposure), giving a Sharpe-ratio-like measure of stock-picking or timing skill per unit of idiosyncratic risk taken.
The formula is as follows:
\[\text{Appraisal Ratio} = \text{Jensen's Alpha} / \text{Residual Standard Deviation}\]Where the residual standard deviation is the standard deviation of the pointwise CAPM regression residuals (Asset Excess Return − Beta * Benchmark Excess Return), reusing the exact same CAPM regression formula as get_jensens_alpha.
See definition: https://en.wikipedia.org/wiki/Information_ratio
Also known as: Treynor-Black Appraisal Ratio.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rolling (int, optional): The rolling window size to use for the Beta component of the
calculation. If set, Beta is estimated over a rolling window of this many periods across
the full return history instead of per
period. Defaults to None. - rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Appraisal Ratio values.
Notes:
- Daily Appraisal Ratio is not an option as the standard deviation for 1 day is close to zero. Therefore, it does not give any useful insights.
- The method retrieves historical data and calculates Jensen’s Alpha and the CAPM
regression residuals for each asset in the Toolkit instance, reusing the same Beta and
CAPM formula as
get_jensens_alpha. - If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_appraisal_ratio()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2022 | -0.0946 | -0.5928 |
| 2023 | 1.4422 | 1.0563 |
| 2024 | 0.3371 | 0.1716 |
| 2025 | -0.5687 | -0.5019 |
| 2026 | 0.1411 | -1.8633 |
get_fama_decomposition
Calculate the Fama (1972) decomposition of total excess return into Selectivity and Diversification.
Jensen’s Alpha alone conflates two very different sources of excess return: genuine stock/timing selection skill, and simply carrying more total risk than the market by holding an under-diversified portfolio (which, in a CAPM world, should be compensated with extra return even absent any skill). Fama’s decomposition separates the two by comparing the portfolio’s actual return against two different CAPM-implied return benchmarks: one using the portfolio’s actual Beta (systematic risk only), and one using the portfolio’s actual total risk ratio (Sigma_Portfolio / Sigma_Market) in place of Beta.
The formulas are as follows:
\[\text{Selectivity} = (\text{Asset Return} - \text{Risk-Free Rate}) - (\text{Sigma\_Portfolio} / \text{Sigma\_Market}) \cdot (\text{Benchmark Return} - \text{Risk-Free Rate})\] \[\text{Diversification} = \left[\text{Risk-Free Rate} + (\text{Sigma\_Portfolio} / \text{Sigma\_Market}) \cdot (\text{Benchmark Return} - \text{Risk-Free Rate})\right] - \left[\text{Risk-Free Rate} + \text{Beta} \cdot (\text{Benchmark Return} - \text{Risk-Free Rate})\right]\]Selectivity is the return earned above what would be required for a fully diversified portfolio carrying the same total risk, i.e. genuine security selection or timing skill. Diversification is the extra return the manager left on the table (if positive, it is a cost) by taking on unsystematic risk that a fully diversified portfolio of the same total risk would not have. Selectivity plus Diversification equals Jensen’s Alpha (see get_jensens_alpha).
Also known as: Fama’s Net Selectivity, Fama performance decomposition.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rolling (int, optional): The rolling window size to use for the Beta component of the
calculation. If set, Beta is estimated over a rolling window of this many periods across
the full return history instead of per
period. Defaults to None. - rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Selectivity and Diversification values, with a Multi Index of (ticker, component) as the columns.
Notes:
- Daily Fama Decomposition is not an option as the standard deviation for 1 day is close to zero. Therefore, it does not give any useful insights.
- The method retrieves historical data and calculates Beta, the asset’s and benchmark’s standard deviation, and the Selectivity and Diversification components for each asset in the Toolkit instance.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_fama_decomposition().xs("AAPL", level=0, axis=1)
Which returns:
| Date | Selectivity | Diversification |
|---|---|---|
| 2021 | 0.0113 | -0.0084 |
| 2022 | 0.022 | -0.0375 |
| 2023 | 0.1048 | 0.0979 |
| 2024 | -0.1053 | 0.1698 |
| 2025 | -0.1774 | 0.056 |
| 2026 | -0.0958 | 0.1246 |
get_starr_ratio
Calculate the STARR (Stable Tail Adjusted Return Ratio) of an investment portfolio or asset’s returns.
The Sharpe ratio penalizes upside and downside volatility equally via the standard deviation. The STARR ratio instead scales the mean excess return by the Conditional Value at Risk (CVaR / Expected Shortfall), a coherent tail-risk measure that only looks at the average magnitude of losses beyond the alpha quantile. This makes STARR more appropriate than the Sharpe ratio for return distributions with fat left tails.
The formula is as follows:
\[\text{STARR Ratio} = \text{Excess Return} / | \operatorname{CVaR}(\alpha) |\]See definition: https://en.wikipedia.org/wiki/Expected_shortfall
Also known as: Stable Tail Adjusted Return Ratio, Conditional Sharpe Ratio.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- within_period (bool, optional): Whether to calculate the CVaR within the specified period or for the entire period. Thus whether to look at the CVaR within a specific year (if period = ‘yearly’) or look at the entirety of all years. Defaults to True.
- alpha (float, optional): The confidence level used for the CVaR calculation (e.g. 0.05 for the worst 5% of outcomes). Defaults to 0.05.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: STARR Ratio values.
Notes:
- The method retrieves historical data and calculates the STARR Ratio for each asset in the Toolkit instance.
- Periods with very few return observations (e.g. a partial period at the very start of the selected date range) can produce a degenerate (e.g. zero or ±infinite) CVaR, since CVaR is not a meaningful statistic with only one or two data points. This mirrors the analogous caveat for the Sharpe Ratio needing enough observations for its standard deviation to be meaningful.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_starr_ratio()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2022 | -0.4203 | -0.4759 |
| 2023 | 1.0763 | 0.8716 |
| 2024 | 0.5566 | 0.4707 |
| 2025 | 0.0677 | 0.0554 |
| 2026 | 0.1743 | -0.3805 |
get_rachev_ratio
Calculate the Rachev Ratio (R-Ratio) of an investment portfolio or asset’s returns.
The Rachev ratio compares the “quality” of the best outcomes to the “quality” of the worst outcomes by taking the ratio of the right-tail Expected Shortfall (the average of the best alpha fraction of returns) to the left-tail Expected Shortfall (the average magnitude of the worst alpha fraction of returns). A ratio above 1 indicates that the average size of extreme gains outweighs the average size of extreme losses.
The formula is as follows:
\[\text{Rachev Ratio} = \operatorname{ES\_right}(\alpha) / \operatorname{ES\_left}(\alpha)\]Also known as: R-Ratio.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- within_period (bool, optional): Whether to calculate the Rachev Ratio within the specified period or for the entire period. Thus whether to look at the return distribution within a specific year (if period = ‘yearly’) or look at the entirety of all years. Defaults to True.
- alpha (float, optional): The confidence level used for both tails (e.g. 0.05 for the best/worst 5% of outcomes). Defaults to 0.05.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Rachev Ratio values.
Notes:
- The method retrieves historical data and calculates the Rachev Ratio for each asset in the Toolkit instance.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_rachev_ratio()
Which returns:
| Date | AAPL | TSLA |
|---|---|---|
| 2022 | 1.0788 | 0.9467 |
| 2023 | 1.0726 | 1.1169 |
| 2024 | 1.1443 | 1.3081 |
| 2025 | 1.0729 | 1.0925 |
| 2026 | 0.8627 | 0.8404 |
get_treynor_mazuy_model
Calculate the Treynor-Mazuy market timing model for each asset in the Toolkit instance.
Jensen’s Alpha and Beta from a plain CAPM regression cannot distinguish stock-picking skill (selectivity) from market-timing skill (shifting exposure ahead of market moves). The Treynor-Mazuy model adds a quadratic term in the benchmark excess return to the regression: a manager who successfully increases (decreases) market exposure ahead of up (down) markets will show a return profile that curves upward as a function of the benchmark return, captured by a positive quadratic coefficient (Gamma).
The formula is as follows:
\[\text{Excess Return} = \text{Alpha} + \text{Beta} \cdot \text{Benchmark Excess Return} + \text{Gamma} \cdot \text{Benchmark Excess Return} ^{2} + \text{Residuals}\]Gamma > 0 indicates positive market-timing ability; Gamma <= 0 indicates no timing ability.
Also known as: Treynor-Mazuy quadratic timing model, TM model.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Alpha, Beta, Gamma and R Squared values, with a Multi Index of (ticker, parameter) as the columns.
Notes:
- Daily and weekly Treynor-Mazuy results are not an option as there would be too few observations within each period to run a meaningful regression.
- The method retrieves historical data and performs a quadratic regression for each asset in the Toolkit instance, within each period.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_treynor_mazuy_model().xs("AAPL", level=0, axis=1)
Which returns:
| Date | Alpha | Beta | Gamma | R Squared |
|---|---|---|---|---|
| 2024 | 0.0009 | 0.944 | -9.4286 | 0.294 |
| 2025 | -0.0005 | 1.2237 | 1.6352 | 0.5693 |
| 2026 | 0.0006 | 0.6632 | -2.6122 | 0.1087 |
get_henriksson_merton_model
Calculate the Henriksson-Merton market timing model for each asset in the Toolkit instance.
Like the Treynor-Mazuy model (see get_treynor_mazuy_model), this separates market-timing skill from selectivity, but models timing as a piecewise (rather than quadratic) change in Beta: a “down-market” Beta and an “up-market” Beta.
The formula is as follows:
\[\text{Excess Return} = \text{Alpha} + \text{Beta} \cdot \text{Benchmark Excess Return} + \text{Up Market Beta} \cdot \max(\text{Benchmark Excess Return},\; 0) + \text{Residuals}\]Beta is the “down-market” Beta (the portfolio’s market exposure when the benchmark excess return is negative), and Beta + Up Market Beta is the “up-market” Beta. Up Market Beta > 0 indicates positive market-timing ability; Up Market Beta <= 0 indicates no timing ability.
Also known as: Henriksson-Merton piecewise timing model, HM model.
Args:
- period (str, optional): The period to use for the calculation. Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”.
- rounding (int, optional): The number of decimals to round the results to. Defaults to 4.
- growth (bool, optional): Whether to calculate the growth of the ratios. Defaults to False.
- lag (int \| str, optional): The lag to use for the growth calculation. Defaults to 1.
- standardize (bool, optional): Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.
Returns:
pd.DataFrame: Alpha, Beta, Up Market Beta and R Squared values, with a Multi Index of (ticker, parameter) as the columns.
Notes:
- Daily and weekly Henriksson-Merton results are not an option as there would be too few observations within each period to run a meaningful regression.
- The method retrieves historical data and performs a piecewise regression for each asset in the Toolkit instance, within each period.
- If
growthis set to True, the method calculates the growth of the ratio values using the specifiedlag.
As an example:
from financetoolkit import Toolkit
toolkit = Toolkit(["AAPL", "TSLA"], api_key="FINANCIAL_MODELING_PREP_KEY")
toolkit.performance.get_henriksson_merton_model().xs("AAPL", level=0, axis=1)
Which returns:
| Date | Alpha | Beta | Up Market Beta | R Squared |
|---|---|---|---|---|
| 2024 | 0.0013 | 1.1387 | -0.3553 | 0.2926 |
| 2025 | -0.0009 | 1.1732 | 0.152 | 0.5673 |
| 2026 | 0.0008 | 0.7243 | -0.1232 | 0.1088 |