Volatility
Calculate the Volatility of an investment portfolio or asset’s returns for a given period based on the daily historical prices.
Volatility measures the amount of dispersion or variability in returns. It is the square root of the Variance. A higher Volatility indicates greater variability, while a lower Volatility suggests that returns are closer to the mean.
By default this is the close-to-close Volatility, i.e. the standard deviation of the daily returns. The method parameter selects one of four range-based estimators instead, each of which uses more of the day’s price action than just the close and is therefore more statistically efficient (i.e. needs fewer observations to reach the same precision), at the cost of additional assumptions about how prices move:
"parkinson"- uses the daily trading range (High vs Low) rather than the close-to-close return, assuming prices follow a continuous geometric Brownian motion with no drift and no overnight jumps."garman_klass"- extends Parkinson by also incorporating the Open and Close, which allows it to account for the opening jump and makes it more efficient still (assuming, as Parkinson does, no drift and no overnight jumps beyond the modeled open)."rogers_satchell"- drift-independent, meaning it remains unbiased even when the underlying asset has a non-zero expected return over the period, at the cost of still assuming no overnight jumps."yang_zhang"- a weighted combination of the overnight (close-to-open) Variance, the open-to-close Variance and the Rogers-Satchell Variance. It is both drift-independent and accounts for overnight jumps, which makes it the most statistically efficient of the range-based estimators implemented here.
The formula is as follows (with the default method=”close_to_close”):
\[\text{Volatility} = \operatorname{Std}(\text{Daily Returns within the period}) \cdot \sqrt{\text{Trading Days per Period}}\]Where Std is the sample standard deviation (ddof=1) and the trading days per period are 252 / 52 (weekly), 252 / 12 (monthly), 252 / 4 (quarterly) or 252 (yearly). The range-based estimators take the square root of a daily variance and scale it the same way, with H, L, O and C the daily High, Low, Open and Close, C_(-1) the previous Close, Mean the average and Var the sample variance (ddof=1) over the days in the period:
\[\text{Parkinson Variance} = \operatorname{Mean}(\ln(H / L) ^{2}) / (4 \cdot \text{ln}\; 2)\] \[\text{Garman-Klass Variance} = \operatorname{Mean}(0.5 \cdot \ln(H / L) ^{2} - (2 \cdot \text{ln}\; 2 - 1) \cdot \ln(C / O) ^{2})\] \[\text{Rogers-Satchell Variance} = \operatorname{Mean}(\ln(H / C) \cdot \ln(H / O) + \ln(L / C) \cdot \ln(L / O))\] \[\text{Yang-Zhang Variance} = \operatorname{Var}(\ln(O / C_{- 1})) + k \cdot \operatorname{Var}(\ln(C / O)) + (1 - k) \cdot \text{Rogers-Satchell Variance}\] \[k = 0.34 / (1.34 + (n + 1) / (n - 1)),\;\; \text{with n the number of days in the period}\]With rolling, the result is the sample standard deviation of the last rolling returns of the chosen period itself, without scaling.
Also known as: standard deviation of returns. The range-based estimators are also known as Parkinson’s range-based or high-low Volatility, Garman-Klass range-based Volatility, Rogers-Satchell drift-independent Volatility and Yang-Zhang drift-independent overnight-aware Volatility.
For more information about the range-based estimators, see the following papers:
- Parkinson, M. (1980). “The Extreme Value Method for Estimating the Variance of the Rate of Return.” Journal of Business, 53(1), 61-65.
- Garman, M.B., & Klass, M.J. (1980). “On the Estimation of Security Price Volatilities from Historical Data.” Journal of Business, 53(1), 67-78.
- Rogers, L.C.G., & Satchell, S.E. (1991). “Estimating Variance from High, Low and Close Prices.” Annals of Applied Probability, 1(4), 504-512.
- Yang, D., & Zhang, Q. (2000). “Drift-Independent Volatility Estimation Based on High, Low, Open, and Close Prices.” Journal of Business, 73(3), 477-491.
Volatility in Python or via the MCP
Install the Finance Toolkit with:
pip install financetoolkit -U
Then call get_volatility as shown below.
from financetoolkit import Toolkit
toolkit = Toolkit(
["EURUSD", "BTCUSD", "^GSPC", "GCUSD"],
api_key="FINANCIAL_MODELING_PREP_KEY",
start_date="2021-01-01",
end_date="2025-12-31",
)
toolkit.risk.get_volatility(period="yearly")
Or, after setting up the Finance Toolkit MCP, ask:
What was the annualized volatility of the euro against the dollar, Bitcoin, the S&P 500 and gold in each year from 2021 to 2025?
Which returns:
| Date | EURUSD | BTCUSD | ^GSPC | GCUSD | Benchmark |
|---|---|---|---|---|---|
| 2021 | 0.0574 | 0.6758 | 0.1 | 0.1156 | 0.0993 |
| 2022 | 0.091 | 0.531 | 0.189 | 0.1216 | 0.1897 |
| 2023 | 0.0764 | 0.3662 | 0.1042 | 0.1088 | 0.104 |
| 2024 | 0.0665 | 0.4441 | 0.098 | 0.1201 | 0.0975 |
| 2025 | 0.0831 | 0.3485 | 0.1457 | 0.1554 | 0.152 |
Parameters
get_volatility accepts the following parameters.
| Parameter | Type | Description | Example |
|---|---|---|---|
period | str | The data frequency for returns (weekly, monthly, quarterly, or yearly). Defaults to “quarterly” if the Toolkit is initialised with quarterly=True, otherwise “yearly”. | "quarterly" |
rolling | int | The rolling window size to use for the calculation. If set, Volatility is calculated over a rolling window of this many periods (e.g. period=’monthly’ and rolling=6 gives the rolling 6-month Volatility) instead of one value per period. Only available for method=”close_to_close”. Defaults to None. | 4 |
method | str | Which Volatility estimator to use, one of “close_to_close”, “parkinson”, “garman_klass”, “rogers_satchell” or “yang_zhang”, as described above. Defaults to “close_to_close”. | "yang_zhang" |
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 Volatility 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 |