Downside Deviation
Calculate the Downside Deviation of an investment portfolio or asset’s returns.
The Downside Deviation, also known as semi-deviation, measures the dispersion of the returns below a minimum acceptable return (MAR), isolating the volatility of negative outcomes from the volatility of the overall return distribution. It underlies risk-adjusted return measures such as the Sortino Ratio and the Omega Ratio.
The formula is as follows (with the default minimum_acceptable_return of 0):
\[\text{Downside Deviation} = \sqrt{\text{Σ} \;\text{min} (\text{Return}_{t} - \text{MAR},\; 0) ^{2} / n}\]Where n is the number of all returns, so returns above the MAR count as a shortfall of zero rather than being left out.
Also known as: semi-deviation, downside risk, downside volatility.
Downside Deviation in Python or via the MCP
Install the Finance Toolkit with:
pip install financetoolkit -U
Then call get_downside_deviation as shown below.
from financetoolkit import Toolkit
toolkit = Toolkit(
["NEE", "DUK", "SO"],
api_key="FINANCIAL_MODELING_PREP_KEY",
start_date="2025-01-01",
end_date="2025-12-31",
)
toolkit.risk.get_downside_deviation()
Or, after setting up the Finance Toolkit MCP, ask:
What was the downside deviation of the daily returns of NextEra Energy, Duke Energy, Southern Company and the S&P 500 over 2025?
Which returns:
| Value | |
|---|---|
| NEE | 0.0124 |
| DUK | 0.0074 |
| SO | 0.0079 |
| Benchmark | 0.0081 |
Parameters
get_downside_deviation accepts the following parameters.
| Parameter | Type | Description | Example |
|---|---|---|---|
period | str | The data frequency for returns (daily, weekly, monthly, quarterly, or yearly). Defaults to “daily”. | "weekly" |
minimum_acceptable_return | float | The minimum acceptable return (MAR) used as the threshold below which returns are considered downside. Defaults to 0.0. | 0.001 |
within_period | bool | Whether to calculate the Downside Deviation within the specified period or for the entire period. Thus whether to look at the Downside Deviation within a specific year (if period = ‘yearly’) or look at the entirety of all years. Defaults to False. Note that this requires intraday data when period = ‘daily’, since a single day only nests observations when intraday data was fetched. | True |
rolling | int | The rolling window size to use for the calculation. If set, the Downside Deviation is calculated over a rolling window of this many periods across the full return history instead of per period. Defaults to None. | 20 |
rounding | int | None | The number of decimals to round the results to. Defaults to None, which uses the rounding of the Toolkit (4 unless set otherwise). | 2 |
growth | bool | Whether to calculate the growth of the Downside Deviation values over time. Defaults to False. | True |
lag | int | list[int] | The lag to use for the growth calculation. Defaults to 1. | 4 |
standardize | bool | Whether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False. | True |