Monte Carlo · Methodology
Monte Carlo Engine Methodology
mc-v1.21.0A complete description of what the forward simulator actually does: where its inputs come from, which return-generating process draws each future day, how drift is resolved, what is subtracted along the way, and how every reported number is defined. Nothing here is a forecast claim. This page exists so you can audit the assumptions behind any probability the product shows you.
For the product-level tour of what the feature does and how to run it, start with Forward Monte Carlo Simulation.
The pipeline, in order
Every simulation runs the same seven stages. Each stage is independently configurable and independently disclosed in the result, which is what makes the output auditable rather than merely plausible-looking.
- 1
Frozen calibration inputs
The simulation loads the exact aligned return panel and CPI series that the parent optimization used, as an immutable content-addressed artifact, and verifies its SHA-256 digest before use. It does not refetch today's market history. Optimized weights and simulated history therefore share one data vintage, and a missing or corrupt artifact fails closed rather than silently substituting fresh data.
- 2
Return-generating process
One of seven selectable processes draws daily asset returns for every path. This is the single biggest modeling choice in the run, and the spread between processes is real model risk rather than noise to be hidden.
- 3
Drift resolution and estimation risk
The centre of the simulated distribution is set by the drift layer, and per-path mean perturbation propagates the fact that the historical mean is itself an estimate with a large standard error.
- 4
Portfolio accounting
Asset returns are aggregated into portfolio wealth under your weights, with rebalancing at the configured frequency and proportional trade costs on every modeled trade.
- 5
Cash flows
SIP contributions and SWP withdrawals are applied on the monthly grid, tracked against a unitized NAV so a deposit is never mistaken for a return. Withdrawals are grossed up for modeled tax and cost.
- 6
Tax and inflation overlays
Realized gains at withdrawals, rebalances and terminal liquidation are taxed under a monthly FIFO cohort approximation, and real-wealth outputs are deflated by CPI aligned to the same historical days the return blocks were sampled from.
- 7
Statistics and intervals
Percentile fans, goal and depletion probabilities with Wilson intervals, drawdown and underwater-spell distributions, and forward VaR/CVaR with separate bootstrap intervals are computed across paths.
The seven return-generating processes
A return-generating process answers one question: given the frozen history, how is tomorrow's cross-section of asset returns drawn? Everything downstream, including the tax and inflation overlays, is identical across processes. Only this stage differs.
None of these has been shown to forecast better than the others. FolioLab does not publish a “best” process, because no rolling-origin validation harness has established one. Running two processes and comparing the range is more informative than trusting any single one.
| Process | Family | Return support | Minimum aligned history |
|---|---|---|---|
| Filtered historical simulation, variance-targeted GJR-GARCH fhs_gjr_garch_vt The default. Models each holding's current volatility with an asymmetric GJR-GARCH fit whose long-run level is pinned to the estimation window, then resamples standardised historical shocks on top. Closest to realised volatility of everything measured, and still not validated out of sample. | Conditional volatility | Log returns, positive gross by construction | About 5 years of jointly aligned rows |
| Filtered historical simulation, GJR-GARCH with a variance-regime layer fhs_gjr_regime The default plus one shared slow-moving variance multiplier, identified on a second and longer window. Adds the year-to-year variation in volatility that a single GARCH component understates. Falls back to no layer, safely, when the history is too short to identify it. | Conditional volatility | Log returns, positive gross by construction | About 5 years to fit, about 10 for the regime layer to activate |
| Filtered historical simulation, regime layer with unconditional fallback fhs_gjr_regime_uv_fallback The variance-regime process, changing only what a holding falls back to when its volatility fit is rejected: its unconditional variance rather than EWMA, which keeps the recursion stationary at the cost of that holding's responsiveness. | Conditional volatility | Log returns, positive gross by construction | About 5 years to fit, about 10 for the regime layer to activate |
| Stationary block bootstrap block_bootstrap Retired, and no longer selectable. Resampled random-length blocks of complete historical days. Rolling-origin testing measured its simulated volatility 27% to 56% above realised at every horizon, so it stopped being the default and no plan grants it. | Resampling | Simple returns, clipped | 4 rows structurally, 32 for automatic block-length selection |
| Regime-switching bootstrap regime_bootstrap A fitted Markov chain moves each path between calm and stressed states; days are resampled from the active state's labeled history. | Resampling | Simple returns, clipped | 252 rows for the regime fit, else falls back to the plain bootstrap |
| Filtered historical simulation, EWMA fhs_ewma Divides history by each holding's estimated volatility, resamples the standardized shock rows, then rebuilds volatility forward from today's level. | Conditional volatility | Log returns, positive | 756 rows, about 3 trading years |
| Filtered historical simulation, GJR-GARCH fhs_gjr_garch The same filter, with a volatility model in which losses raise future risk more than equivalent gains. Failed fits fall back to EWMA per asset. | Conditional volatility | Log returns, positive | 1,260 rows, about 5 trading years |
| Lognormal GBM gbm_lognormal Independent Gaussian log returns with a Ledoit-Wolf shrinkage covariance. An analytical reference point, not a realism upgrade. | Parametric benchmark | Log returns, positive | 60 rows |
| Multivariate Student-t student_t Fat-tailed draws with covariance matched to history and one shared mixing variable per day, so the cross-section fattens together. | Parametric comparison | Simple returns, clipped | 4 rows |
| Multivariate Gaussian gaussian Normal draws on the historical mean and covariance. The thin-tailed reference case: it understates Indian-market tails by design. | Parametric comparison | Simple returns, clipped | 4 rows |
Why return support matters
The three log-domain processes build gross returns as where is a simulated log return. Gross returns are therefore positive by construction: a holding can approach zero but can never go through it, and no corrective clipping exists on those paths.
The four simple-return processes can in principle emit a gross return at or below zero. A disclosed lower gross-return clip prevents negative wealth. The clip is reported with the result, including how often it bound, so you can see whether it was cosmetic or load-bearing. For the bootstrap families it is effectively inert, because resampled historical rows never contain a total loss. For the Gaussian and Student-t processes it is a real part of the model, which is one reason both are labeled comparison processes rather than planning models.
What every process shares
Whole-row sampling
Batch-stable state
Common random numbers
Reproducibility
Variance reduction
For the plain block bootstrap, the first block start of every path is stratified over the historical index rather than drawn uniformly: path of draws its opening row uniformly inside the stratum
where is the number of historical rows. This is a Latin hypercube-style stratification. It guarantees the set of starting points covers the whole sample evenly instead of clustering by chance, which tightens tail-quantile estimates at no computational cost and without changing the target distribution.
Stratification is disabled when a crisis scenario supplies over-sampling weights, because weighted starts and stratified starts make contradictory assumptions about the start distribution. The regime bootstrap also draws first starts uniformly within the opening regime's rows, so it does not stratify either.
Validation status of each process
Selectability and validation are separate facts, and the engine reports them separately. Every process listed above is fully specified, implemented and selectable. None of them has passed out-of-sample validation.
The log-return generators publish validation_status: rejected_by_rolling_origin_validation together with the policy version that produced the verdict. That wording is deliberate: the harness has run and returned a result, so describing them merely as “unvalidated” would understate evidence the product already has. The stationary block bootstrap remains the operational default because it is the incumbent, not because it won a comparison.
A regime-FHS and MSGARCH core is implemented and unit-tested but is deliberately absent from the selectable process enum, from billing and from every product surface, after failing its rolling-origin activation gates. The all-or-nothing state is the safety property: a partially wired generator that can be reached by one code path and not another is the failure this design prevents. See rolling-origin validation for the measured evidence, and model risk for what an empty accepted cohort does to the reported numbers.
Availability by plan
Process availability is a plan entitlement. Pro includes six of the seven: block_bootstrap, regime_bootstrap, fhs_ewma, gbm_lognormal, gaussian and student_t. Enterprise adds fhs_gjr_garch, the compute-heaviest fit. The configuration form shows processes outside your entitlement as disabled with the reason rather than hiding them, and a request for a process you cannot run is rejected with 403 mc_process_not_allowed rather than being silently downgraded to something else.
Path counts are capped separately: 50,000 per run on Pro and 100,000 on Enterprise, with a workload safety limit that can further restrict presets for long horizons, many assets, or several scenarios at once. More paths reduce sampling noise in the reported probabilities. They do not reduce model uncertainty, which is what the process comparison is for.
The rest of the methodology
Drift and estimation risk
The mean return is the hardest input in the model. What the four drift modes do, and why per-path mean perturbation is on by default.
Inflation, tax, cash flows and costs
Everything subtracted between a simulated return and reported wealth, including exactly what the tax model does not cover.
Output statistics
Precise definitions for percentile fans, goal bases, Wilson intervals, drawdown measures, forward VaR and CVaR, and depletion.
Parameter uncertainty
What is treated as a fixed assumption versus a sampling estimate, and the opt-in refit experiment that propagates the difference.
Walk-forward re-optimization
Re-fitting the optimizer on every path: the eligible methods, the policy knobs, the paired control arm and cost attribution.
Crisis and stress scenarios
Historical replay arms and four deterministic market-mechanics stresses, all under common random numbers.
History governance
Window length is not window content. The drawdown-episode disclosure and the instrument master behind admission.
Adaptive precision
Sequential stopping on time-uniform confidence sequences, the four tiers, and the asymptotic-claim guard.
Rolling-origin validation
The out-of-sample harness that scores these generators, and the published verdict that none has been accepted.
References
- Politis, D. N., & Romano, J. P. (1994). The Stationary Bootstrap. Journal of the American Statistical Association, 89(428), 1303–1313.
- Politis, D. N., & White, H. (2004). Automatic Block-Length Selection for the Dependent Bootstrap. Econometric Reviews, 23(1), 53–70.
- Patton, A., Politis, D. N., & White, H. (2009). Correction to Automatic Block-Length Selection for the Dependent Bootstrap. Econometric Reviews, 28(4), 372–375.
- Hamilton, J. D. (1989). A New Approach to the Economic Analysis of Nonstationary Time Series and the Business Cycle. Econometrica, 57(2), 357–384.
- Barone-Adesi, G., Giannopoulos, K., & Vosper, L. (1999). VaR without Correlations for Portfolios of Derivative Securities. Journal of Futures Markets, 19(5), 583–602.
- Glosten, L. R., Jagannathan, R., & Runkle, D. E. (1993). On the Relation between the Expected Value and the Volatility of the Nominal Excess Return on Stocks. Journal of Finance, 48(5), 1779–1801.
- Newey, W. K., & West, K. D. (1987). A Simple, Positive Semi-Definite, Heteroskedasticity and Autocorrelation Consistent Covariance Matrix. Econometrica, 55(3), 703–708.
- Ledoit, O., & Wolf, M. (2004). A Well-Conditioned Estimator for Large-Dimensional Covariance Matrices. Journal of Multivariate Analysis, 88(2), 365–411.
- Wilson, E. B. (1927). Probable Inference, the Law of Succession, and Statistical Inference. Journal of the American Statistical Association, 22(158), 209–212.