Your track record is one sample of what could have happened. Monte Carlo resamples or models your daily returns to generate thousands of alternative paths, so you can see the range of outcomes instead of a single line — and estimate the odds of deep drawdowns or ruin.
You can run it on the whole portfolio or a single strategy. Active weekday filters are respected.
The series fed to the simulation is built from trading days only — the days you actually had a position. Idle calendar days (weekends, holidays, gaps between trades) are not part of the resampling pool, for the portfolio exactly as for a single strategy. This keeps both runs on the same footing: the horizon below is counted in trading days, and the portfolio simulation is directly comparable to the single-strategy one (no diluted volatility, no drift collapsing toward zero from padded idle days).
When at least one strategy uses dynamic sizing (and the source is the portfolio, or that sized strategy), the simulator switches engine automatically: instead of resampling a produced P/L series, it resamples the raw trades in calendar blocks and re-runs the allocation inside every path — capital, compounding and the daily risk budget react to each simulated history, so the capital→size feedback loop is genuinely stressed. In a hybrid portfolio each block carries the sized trades and the fixed legs' daily P/L of the same period, preserving the correlation between legs; fixed-leg P/L enters the compounding capital from the next day and never consumes the max daily risk. Manual costs on sized legs are subtracted per path, so the bands are net and match the historical reference line.
One thing the per-path allocator doesn't model
The margin cap (safe-80% / limit-100%) is applied by the historical reference curve but not inside the simulated paths. When you run a dynamic Monte Carlo with a margin cap active and margin data present, the results carry a warning: with the cap biting, the simulated position sizes — and therefore returns and ruin probability — can read slightly optimistic versus reality. Everything else (sizing, daily risk budget, compounding, costs) is modelled per path.
What changes in the controls, and why:
The verdict compares the dynamic path (the real engine re-run per path) against a fixed sizing benchmark (contracts computed once on the initial capital), with ruin probability, final distribution and drawdown read off the dynamic paths. Selecting a single fixed strategy as the source keeps the classic series engine below, untouched.
The dynamic run exposes the same result tabs as the fixed-contract one — Statistics, Distributions (final-value and max-drawdown histograms) and Horizons — all read off the dynamic paths. One reading caveat: with Compounding on, position size follows the account, so the final-value distribution is naturally right-skewed (a long right tail by construction) — read the median and percentiles, not just the maximum. In the Horizons ladder the "days" are the path's close-day steps (the dynamic fan has no fixed trading-day horizon), so treat them as sequence checkpoints rather than calendar days.
The classic Monte Carlo models a fixed-contract book. It resamples the daily P/L in dollars
and rebuilds equity additively (equity = capital + Σ P/L): a +$400 day is +$400 wherever the path
sits — the dollar P/L does not grow with the account. This is the honest model for a strategy that
trades a fixed number of contracts (e.g. always 1 lot), and it is the only mode here — there is no
"compounding %" toggle.
An absorbing ruin barrier is active: a path that touches the ruin level stops there (a real account that draws down that far can no longer post margin to keep trading), so the ruin probability is meaningful and responds to your starting capital.
Want to study scaling with capital?
Compounding — position size that grows with the account — is not a Monte Carlo toggle, because on a fixed-lot series it is a fiction: a constant ±$400/day is a big % on a small early account and a tiny % on a large late one, so compounding those percentages manufactures exponential growth the strategy can never realise (inflating the median, driving ruin to ~0, making drawdown vanish). To model scaling faithfully, switch the strategy to dynamic sizing in the workspace (risk- or margin-based): it recomputes the contract count each day from your current capital and risk rules, honouring integer contracts and margin. The Monte Carlo then automatically runs in its dynamic form — resampling trades in blocks and re-running that real allocation in every path, governed by the workspace's own Compounding switch and max daily risk (see With dynamic sizing above) — instead of naively compounding percentage returns off a fixed-lot series.
VEEMAN offers six models, from production-grade to didactic. Block bootstrap is the default and a safe general choice.
| Model | What it does | Use it when |
|---|---|---|
| FHS + GARCH(1,1) | Filtered Historical Simulation: fits a GARCH conditional-volatility model and bootstraps its standardised residuals. The market standard for VaR. | Returns show volatility clustering (calm and stormy regimes). |
| Block bootstrap | Stationary bootstrap (Politis–Romano): resamples blocks of consecutive days, preserving autocorrelation and clustering. | A robust default — structure without a parametric model. |
| Skewed Student-t | Fernández–Steel distribution: captures skew + fat tails, with degrees of freedom and skew fitted by MLE. | Returns are asymmetric (e.g. short-vol, crash risk). |
| Student-t | Symmetric fat-tailed distribution fitted by MLE, re-centred on the empirical mean. | Symmetric returns with tail risk. |
| Bootstrap (IID) | Resamples single days independently. Destroys serial dependence and underestimates drawdowns. | Teaching / baseline only. |
| Gaussian GBM | Log-normal random walk. Ignores fat tails. | Teaching / baseline only. |
IID and Gaussian are didactic
The last two models deliberately ignore real-world structure (clustering, fat tails). They're useful to show why the others matter — not to size real risk. Prefer Block bootstrap or FHS+GARCH for decisions.
Why the Student-t model is re-centred
The Student-t is symmetric, so the mean of the values it generates is exactly its fitted location. On a skewed sample that location settles on the bulk of the data and absorbs the few large losses into the tail — it behaves like a median, not a mean.
For a premium-selling strategy the gap can invert the conclusion: 99 days at +$100 and one at −$15,000 average −$51 a day, while the fitted location sits near +$100. Left as-is, the simulation would show near-certain growth for a strategy that loses money.
VEEMAN therefore centres the simulated drift on the empirical mean, so that
E[equity at horizon] = capital + horizon × mean(P/L) — the property block bootstrap, IID bootstrap and
Gaussian already have. The fitted location is still reported in the diagnostics, and when it diverges
from the mean by more than sampling noise the run carries a warning suggesting block bootstrap or
skewed-t instead. This is a deliberate modelling choice: it trades the model's status as a strict MLE
fit for a drift that matches your actual track record.
A run returns several views:
The Horizons tab answers a specific question: what should I expect over the next 10, 15, 30… trading days? It reads the same percentile fan at intermediate days — no extra simulation — and lays out, for a ladder of horizons (5, 10, 15, 21, 30, 63, 126 ≈ six months, 252 ≈ one year trading days, plus your full horizon), the P/L relative to the initial capital:
A per-row bar shows the band widening as the horizon grows — the visual signature that short-term outcomes are dominated by chance: over a handful of days the drift (days × mean) is tiny next to the spread (√days × volatility), so the honest reference is the range, not a point. The 10-day horizon is the classic regulatory VaR window, so these near-term bands are a standard, solid reference. The last row is your full horizon, so it ties back to the numbers in Statistics.
Equity band only — drawdown and tails stay terminal
The Horizons tab reads the equity percentile bands at each day. The max drawdown and the fine tails (VaR / CVaR) are cumulative to the path endpoint, so they remain in the Statistics tab, referred to the full horizon. If you need those risk metrics at one specific short horizon, run the simulation with that horizon set directly.
| Stat | Meaning |
|---|---|
| Probability of ruin | share of paths that touch the ruin threshold at any point. In fixed-contract mode the barrier is absorbing, so this responds to your starting capital. |
| Prob. below capital | share of scenarios that end below the starting capital — the plain "chance of losing money". |
| Median / P05 / P95 final | typical and tail outcomes for final equity. |
| Max DD median / P95 | typical and bad-case worst drawdowns, shown in % of peak and in dollars. |
| Tail P/L 5% & 1% (VaR / CVaR) | the final P/L in dollars at the 5th / 1st percentile (VaR) and the average P/L of that worst tail (CVaR). Negative = a loss; positive = even the tail is a gain (a profitable strategy at a long horizon). Computed on terminal dollars, so there is no "−1,129%" artefact from compounded returns. |
Each run also reports the fitted model internals — for FHS+GARCH that includes the persistence (α + β), the volatility half-life in days and the long-run volatility; for the t-models, the fitted degrees of freedom and skew; for bootstraps, the block length used. These let you sanity-check that the model captured your data.
For the Student-t the degrees of freedom are reported twice: the raw MLE estimate and the value
actually used. VEEMAN floors ν at 2.1 so the simulated distribution has a finite variance — without
it, drawdown and ruin statistics would not converge. When the raw estimate falls below that floor the
run says so, because a reported 2.10 on an estimate of 1.04 describes the floor, not your data.
It's still a model
Monte Carlo assumes the future resembles the resampled past. It widens your view of risk, but it cannot foresee regime changes the history never contained. Treat the ruin probability as a relative gauge across configurations, not a guarantee.
A million paths over a 1,260-day horizon is heavy but feasible; 1,000–10,000 simulations are plenty for interactive work, with 100,000+ reserved for final risk reports. Runs are offloaded to a worker thread so the UI stays responsive.
You can leave the tab while it runs
The simulation runs on the server as a background job: launching it returns immediately and the app polls for the result. You can switch tabs, open another app, or lock your phone — the run keeps going server-side and the result appears when you come back. The job is self-contained and saved, so it survives a page reload — and even a server restart: if the backend recycles mid-run, the next poll transparently re-runs it from the stored recipe.