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.

ParameterTypeDescriptionExample
periodstrThe data frequency for returns (daily, weekly, monthly, quarterly, or yearly). Defaults to “daily”."weekly"
minimum_acceptable_returnfloatThe minimum acceptable return (MAR) used as the threshold below which returns are considered downside. Defaults to 0.0.0.001
within_periodboolWhether 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
rollingintThe 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
roundingint | NoneThe number of decimals to round the results to. Defaults to None, which uses the rounding of the Toolkit (4 unless set otherwise).2
growthboolWhether to calculate the growth of the Downside Deviation values over time. Defaults to False.True
lagint | list[int]The lag to use for the growth calculation. Defaults to 1.4
standardizeboolWhether to standardize (Z-Score) the result. When combined with growth=True, standardizes the growth values instead of the raw values. Defaults to False.True
Share