Simulate uncertainty
Choose an input distribution and call ctx.draw() or ctx.sample() in a model callback so each trial uses a sampled value.
import { cashflow, currencies, defineModel, entity, inflow, input, periods, runMonteCarlo, schedule } from "deccf";
const growth = input.normal({ mean: 0.02, stdev: 0.01, clip: [0, 0.05] });
const company = entity.asset();
const revenue = cashflow({
owner: company,
direction: inflow,
schedule: schedule.annual(),
amount: (ctx) => 100_000 * (1 + ctx.draw(growth)) ** ctx.time.index,
});
const model = defineModel({
name: "growth",
currency: currencies.SEK,
timeline: periods.annual({ from: "2026-01", count: 10 }),
preconditions: { growth },
entities: { company },
flows: { revenue },
});
const simulation = runMonteCarlo(model, { trials: 2_000, seed: 7 });
console.log(simulation.summaries["model.total"].mean);
return model;Available distributions are normal, logNormal, uniform, and triangular. Put clip on the distribution parameters; it limits the central value and samples. Input types and domain can add further validation. The engine does not provide a correlation matrix.
runMonteCarlo() requires a positive integer trials count and an integer seed. Summaries include mean, standard deviation, minimum, maximum, and percentiles p5, p25, p50, p75, and p95.
In the Calculator, open Run input, choose Monte Carlo, then set the trial count and seed before selecting Run model. The summary view shows the numeric metrics returned by the simulation; period-by-period reports are only available from a regular deterministic run.
ctx.get(growth) always returns the distribution's central value. ctx.draw(growth) reuses a draw across periods within one trial. ctx.sample(growth) draws separately by period and owner. A plain run(model) uses the central value when a callback calls draw() or sample() without a seed and trial.