Jarque-Bera Test
Calculate the Jarque-Bera test for normality.
The test combines sample skewness and excess kurtosis into a single statistic that is chi-squared distributed with 2 degrees of freedom under the null hypothesis that returns are normally distributed. A significant result (low p-value) indicates that returns are not normally distributed, which is relevant when choosing between e.g. gaussian and Student-T based Value at Risk models.
The formula is as follows:
\[\text{JB} = (n / 6) \cdot (S ^{2} + (K - 3) ^{2} / 4),\;\; \text{chi-squared with 2 degrees of freedom}\] \[S = \text{m₃} / \text{m₂} ^{3 / 2} \text{and}\; K = \text{m₄} / \text{m₂} ^{2},\;\; \text{with}\; \text{mₖ} = (1 / n) \cdot \operatorname{Σ}(\text{rₜ} - \operatorname{mean}(r)) \text{ᵏ} \;\text{the} (\text{biased}) \text{central moments of the returns of}\; \text{period}\]For more information about the method, see the following paper:
- Jarque, C.M. and Bera, A.K. (1987). “A Test for Normality of Observations and Regression Residuals.” International Statistical Review, 55(2), 163-172.
Also known as: JB test, normality test.
Jarque-Bera Test in Python or via the MCP
Install the Finance Toolkit with:
pip install financetoolkit -U
Then call get_jarque_bera_test as shown below.
from financetoolkit import Toolkit
toolkit = Toolkit(
["^GSPC", "BTCUSD", "TLT"],
api_key="FINANCIAL_MODELING_PREP_KEY",
start_date="2021-01-01",
end_date="2025-12-31",
)
toolkit.econometrics.get_jarque_bera_test(period="monthly")
Or, after setting up the Finance Toolkit MCP, ask:
Were the monthly returns of the S&P 500, Bitcoin and the iShares 20+ Year Treasury Bond ETF (TLT) normally distributed from 2021 to 2025, according to the Jarque-Bera test?
Which returns:
| ^GSPC | BTCUSD | TLT | |
|---|---|---|---|
| Jarque-Bera Statistic | 2.6001 | 1.0834 | 0.6166 |
| P-Value | 0.2725 | 0.5818 | 0.7347 |
Using Your Own Data
get_jarque_bera_test runs on any data, not only prices: ratios, economic indicators, yield curves or your own dataset. Pass a DataFrame, a Series or a dictionary of them to Econometrics as data, with the dates in the rows or the columns, and set changes to how its changes are calculated: "percentage", "log", "difference" for rates and ratios, or None when the data are changes already. For example, for the monthly unemployment rates of the United States and Germany:
from financetoolkit import Economics, Econometrics
economics = Economics(start_date="2000-01-01")
unemployment = economics.get_unemployment_rate(
countries=["United States", "Germany"], period="monthly"
)
econometrics = Econometrics(data=unemployment, changes="difference")
econometrics.get_jarque_bera_test()
Parameters
get_jarque_bera_test 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" |
within_period | bool | Whether to calculate the test within the specified period or for the entire period. Thus whether to look at the test 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 |
include_benchmark | bool | Whether to include “Benchmark” among the assets tested. Defaults to False. | True |
rounding | int | None | The number of decimals to round the results to. Defaults to None. | 2 |