mfe.bootstrap¶
mfe.bootstrap ¶
mfe.bootstrap — Dependent-data bootstrap methods.
wild_bootstrap_rv Wild bootstrap CI for realized volatility statistics wild_bootstrap_test Wild bootstrap p-value for hypothesis tests spa_test Hansen (2005) Superior Predictive Ability test step_m Romano-Wolf (2005) Stepdown Multiple Hypothesis Test (FWER control)
WildBootstrapResult
dataclass
¶
WildBootstrapResult(statistic: float, ci_lower: float, ci_upper: float, ci_level: float, bootstrap_distribution: FloatArray, n_replications: int, multiplier: str)
Result from a wild bootstrap confidence interval computation.
StepMResult
dataclass
¶
StepMResult(rejected: list[int], accepted: list[int], t_stats: FloatArray, p_values_raw: FloatArray, p_values_adjusted: FloatArray, n_models: int, n_obs: int, n_bootstrap: int, alpha: float)
StepM multiple hypothesis testing result.
wild_bootstrap_rv ¶
wild_bootstrap_rv(returns: FloatArray, statistic_fn: Callable[[FloatArray], float] | None = None, n_replications: int = 999, ci_level: float = 0.95, multiplier: str = 'rademacher', rng: Generator | None = None) -> WildBootstrapResult
Wild bootstrap confidence interval for a realized volatility statistic.
The bootstrap DGP is: r_t^* = w_t * r_t
where w_t is i.i.d. from the specified multiplier distribution. The statistic is re-evaluated on {r_t^*}.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
returns
|
FloatArray
|
|
required |
statistic_fn
|
Callable[[FloatArray], float] | None
|
|
None
|
n_replications
|
number of bootstrap replications
|
|
999
|
ci_level
|
float
|
|
0.95
|
multiplier
|
str
|
|
'rademacher'
|
rng
|
Generator | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
WildBootstrapResult
|
|
Source code in src/mfe/bootstrap/wild.py
wild_bootstrap_test ¶
wild_bootstrap_test(returns: FloatArray, null_statistic: float, statistic_fn: Callable[[FloatArray], float] | None = None, n_replications: int = 999, multiplier: str = 'rademacher', rng: Generator | None = None) -> tuple[float, float]
Wild bootstrap p-value for a two-sided hypothesis test.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
null_statistic
|
the value of the statistic under the null hypothesis
|
|
required |
Returns:
| Type | Description |
|---|---|
(observed_statistic, bootstrap_p_value)
|
|
Source code in src/mfe/bootstrap/wild.py
spa_test ¶
spa_test(loss_benchmark: FloatArray, loss_models: FloatArray, n_bootstrap: int = 999, avg_block_len: float | None = None, bandwidth: int | None = None, rng: Generator | None = None) -> SPAResult
Hansen (2005) Superior Predictive Ability test.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
loss_benchmark
|
(T,) loss series for the benchmark model (lower = better)
|
|
required |
loss_models
|
FloatArray
|
|
required |
n_bootstrap
|
int
|
|
999
|
avg_block_len
|
float | None
|
|
None
|
bandwidth
|
int | None
|
|
None
|
rng
|
Generator | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
SPAResult
|
Report .p_value_consistent for the standard SPA p-value. Report .p_value_upper for White's Reality Check p-value. |
Notes
Loss convention: LOWER is BETTER (e.g. MSE, MAE, negative log-lik). Loss differential d_{k,t} = L_benchmark_t - L_model_k_t. Positive d_bar_k means model k beats benchmark on average.
Source code in src/mfe/bootstrap/spa.py
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | |
step_m ¶
step_m(loss_benchmark: FloatArray, loss_models: FloatArray, alpha: float = 0.05, n_bootstrap: int = 999, avg_block_len: float | None = None, bandwidth: int | None = None, rng: Generator | None = None) -> StepMResult
Romano-Wolf StepM stepdown multiple hypothesis test.
Tests H_k: E[L_bench - L_model_k] <= 0 for k = 1..M. Rejects H_k (model k beats benchmark) for k in result.rejected. Controls FWER <= alpha across all M tests.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
loss_benchmark
|
(T,) benchmark loss series (lower = better)
|
|
required |
loss_models
|
FloatArray
|
|
required |
alpha
|
float
|
|
0.05
|
n_bootstrap
|
int
|
|
999
|
avg_block_len
|
float | None
|
|
None
|
bandwidth
|
int | None
|
|
None
|
rng
|
Generator | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
StepMResult
|
.rejected — 0-based indices of models significantly beating benchmark .accepted — the rest |
Source code in src/mfe/bootstrap/stepM.py
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | |
spa ¶
Superior Predictive Ability (SPA) test — Hansen (2005).
Hansen, P.R. (2005): "A Test for Superior Predictive Ability", Journal of Business & Economic Statistics, 23(4), 365-380.
Also implements White (2000) Reality Check as a special case.
Setup
Given M models and a benchmark, let d_{k,t} = L(y_t, f_{0,t}) - L(y_t, f_{k,t}) be the loss differential at time t for model k vs. benchmark (model 0). d_{k,t} > 0 means model k is better than benchmark at time t.
H0: max_k E[d_{k,t}] <= 0 (no model beats the benchmark on average) H1: max_k E[d_{k,t}] > 0 (at least one model is strictly better)
Test statistic
T_SPA = max_k ( sqrt(T) * d_bar_k / sigma_k ) where d_bar_k = mean(d_{k,t}) and sigma_k^2 is the long-run variance of d_{k,t}.
Under H0, T_SPA has a distribution that depends on the correlation structure of {d_{k,t}} across k. P-values are computed by the stationary bootstrap.
Hansen's SPA uses a "studentized" version with three variants of the null: - "consistent" (default): removes irrelevant models from the null (d_bar_k << 0) - "upper": retains all models (equivalent to White's Reality Check) - "lower": most conservative, all models treated as tied with benchmark
References
White, H. (2000): "A Reality Check for Data Snooping", Econometrica.
spa_test ¶
spa_test(loss_benchmark: FloatArray, loss_models: FloatArray, n_bootstrap: int = 999, avg_block_len: float | None = None, bandwidth: int | None = None, rng: Generator | None = None) -> SPAResult
Hansen (2005) Superior Predictive Ability test.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
loss_benchmark
|
(T,) loss series for the benchmark model (lower = better)
|
|
required |
loss_models
|
FloatArray
|
|
required |
n_bootstrap
|
int
|
|
999
|
avg_block_len
|
float | None
|
|
None
|
bandwidth
|
int | None
|
|
None
|
rng
|
Generator | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
SPAResult
|
Report .p_value_consistent for the standard SPA p-value. Report .p_value_upper for White's Reality Check p-value. |
Notes
Loss convention: LOWER is BETTER (e.g. MSE, MAE, negative log-lik). Loss differential d_{k,t} = L_benchmark_t - L_model_k_t. Positive d_bar_k means model k beats benchmark on average.
Source code in src/mfe/bootstrap/spa.py
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | |
stepM ¶
StepM: Stepdown Multiple Hypothesis Testing with FWER control.
Romano, J.P. & Wolf, M. (2005): "Stepwise Multiple Testing as Formalized Data Snooping", Econometrica, 73(4), 1237-1282.
Setup
M null hypotheses H_k: mu_k <= 0 for k = 1..M, where mu_k = E[d_{k,t}] is the mean performance differential of model k vs. the benchmark.
The algorithm controls the familywise error rate (FWER): FWER = P(reject at least one true H_k) <= alpha
This is more powerful than Bonferroni and more interpretable than SPA: it returns which models are significantly better, not just whether any is.
Algorithm (Algorithm 4.1 of Romano & Wolf 2005)
- Start with all M models.
- Compute test statistics t_k = sqrt(T) * d_bar_k / sigma_k.
- Use the stationary bootstrap to get the joint null distribution of max_k t_k (over the remaining models).
- Reject the model with the largest t_k if it exceeds the bootstrap critical value at level alpha.
- Remove rejected models from the set and repeat.
- Stop when no more rejections occur.
The result is a set of models significantly better than the benchmark.
This matches the MFE MATLAB implementation under bootstrap/stepm.m.
StepMResult
dataclass
¶
StepMResult(rejected: list[int], accepted: list[int], t_stats: FloatArray, p_values_raw: FloatArray, p_values_adjusted: FloatArray, n_models: int, n_obs: int, n_bootstrap: int, alpha: float)
StepM multiple hypothesis testing result.
step_m ¶
step_m(loss_benchmark: FloatArray, loss_models: FloatArray, alpha: float = 0.05, n_bootstrap: int = 999, avg_block_len: float | None = None, bandwidth: int | None = None, rng: Generator | None = None) -> StepMResult
Romano-Wolf StepM stepdown multiple hypothesis test.
Tests H_k: E[L_bench - L_model_k] <= 0 for k = 1..M. Rejects H_k (model k beats benchmark) for k in result.rejected. Controls FWER <= alpha across all M tests.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
loss_benchmark
|
(T,) benchmark loss series (lower = better)
|
|
required |
loss_models
|
FloatArray
|
|
required |
alpha
|
float
|
|
0.05
|
n_bootstrap
|
int
|
|
999
|
avg_block_len
|
float | None
|
|
None
|
bandwidth
|
int | None
|
|
None
|
rng
|
Generator | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
StepMResult
|
.rejected — 0-based indices of models significantly beating benchmark .accepted — the rest |
Source code in src/mfe/bootstrap/stepM.py
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | |
wild ¶
Wild bootstrap for realized volatility and related statistics.
Gonçalves, S. & Meddahi, N. (2009): "Bootstrapping Realized Volatility", Econometrica, 77(1), 283-306.
The wild bootstrap resamples by multiplying each squared return by an i.i.d. multiplier w_t drawn from a two-point distribution that matches the first two moments of the standard normal.
This is appropriate for realized volatility statistics because: 1. The squared-return sequence has heterogeneous conditional variance. 2. Block resampling destroys the i.i.d.-ness of squared returns under the null. 3. The wild bootstrap is consistent for RV-based test statistics even in the presence of microstructure noise (with appropriate pre-averaging).
Two-point Rademacher multiplier: w_t = +1 or -1 with prob 1/2. Mammen (1993) multiplier: w_t = -(sqrt(5)-1)/2 or (sqrt(5)+1)/2.
WildBootstrapResult
dataclass
¶
WildBootstrapResult(statistic: float, ci_lower: float, ci_upper: float, ci_level: float, bootstrap_distribution: FloatArray, n_replications: int, multiplier: str)
Result from a wild bootstrap confidence interval computation.
wild_bootstrap_rv ¶
wild_bootstrap_rv(returns: FloatArray, statistic_fn: Callable[[FloatArray], float] | None = None, n_replications: int = 999, ci_level: float = 0.95, multiplier: str = 'rademacher', rng: Generator | None = None) -> WildBootstrapResult
Wild bootstrap confidence interval for a realized volatility statistic.
The bootstrap DGP is: r_t^* = w_t * r_t
where w_t is i.i.d. from the specified multiplier distribution. The statistic is re-evaluated on {r_t^*}.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
returns
|
FloatArray
|
|
required |
statistic_fn
|
Callable[[FloatArray], float] | None
|
|
None
|
n_replications
|
number of bootstrap replications
|
|
999
|
ci_level
|
float
|
|
0.95
|
multiplier
|
str
|
|
'rademacher'
|
rng
|
Generator | None
|
|
None
|
Returns:
| Type | Description |
|---|---|
WildBootstrapResult
|
|
Source code in src/mfe/bootstrap/wild.py
wild_bootstrap_test ¶
wild_bootstrap_test(returns: FloatArray, null_statistic: float, statistic_fn: Callable[[FloatArray], float] | None = None, n_replications: int = 999, multiplier: str = 'rademacher', rng: Generator | None = None) -> tuple[float, float]
Wild bootstrap p-value for a two-sided hypothesis test.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
null_statistic
|
the value of the statistic under the null hypothesis
|
|
required |
Returns:
| Type | Description |
|---|---|
(observed_statistic, bootstrap_p_value)
|
|