xellstorm Open the app

Moving a model from @RISK, ModelRisk or Analytic Solver

Guide · Updated October 2026

xellstorm opens a workbook built for @RISK, ModelRisk or Analytic Solver without the add-in, reads 164 of their distribution functions, and turns each such formula into an input whose parameters stay linked to your cells. Before you run, it lists what it converted and every formula it left, with the reason.

The 164 functions are 53 of @RISK, 62 of ModelRisk and 49 of Analytic Solver. It also reads 65 forms that give a distribution by its percentiles, along with truncation, output markers, correlation matrices and multi-simulation tables.

What the import finds in a workbook written for @RISK

The example is the building estimate of the project contingency example, written the way a model built for @RISK would be: each cost item is =RiskPert(min, most likely, max, RiskName(label)) on the cells of its row, each risk event is a RiskBernoulli on its probability, the total cost and the overrun are marked with RiskOutput, Structure and MEP are correlated through RiskCorrmat, three budgets sit in one RiskSimtable, and a cell reports RiskMean of the total. A second sheet, “Demonstrations”, holds five separate formulas: two arithmetic forms that do convert and three formulas that do not. We made the file with a script; xellstorm does not need @RISK to read it, and neither do you.

In the app, Import from workbook on the Distributions step lists the formulas it found (the command line’s xellstorm import prints the same list). For this workbook it converts 12 inputs: the 6 cost items, the 4 risk events and 2 arithmetic demonstrations. The cost items and risk events keep their parameters linked to the cells, so editing a min or a probability in the workbook changes the next run, and RiskName(A3) names each input after the text in its row. The two that convert are a Normal draw multiplied by a factor, and one whose mean is calculated from another cell. Neither is used by the estimate’s outputs.

What the import converts in the workbook (linked cells in parentheses, with the value they hold)
CellFormula in the workbookBecomes
E3=RiskPert(B3,C3,D3,RiskName(A3))Site work: a PERT with min B3 (100), most likely C3 (120), max D3 (170)
E4=RiskPert(B4,C4,D4,RiskName(A4))Foundation: a PERT with min B4 (300), most likely C4 (340), max D4 (460)
E5=RiskPert(B5,C5,D5,RiskName(A5),RiskCorrmat(Correlation,1))Structure: a PERT with min B5 (760), most likely C5 (820), max D5 (1,010)
E6=RiskPert(B6,C6,D6,RiskName(A6),RiskCorrmat(Correlation,2))MEP: a PERT with min B6 (540), most likely C6 (610), max D6 (780)
E7=RiskPert(B7,C7,D7,RiskName(A7))Finishes: a PERT with min B7 (400), most likely C7 (450), max D7 (560)
E8=RiskPert(B8,C8,D8,RiskName(A8))Equipment: a PERT with min B8 (260), most likely C8 (280), max D8 (330)
D11=RiskBernoulli(B11,RiskName(A11))Ground conditions: a Bernoulli with probability B11 (0.25)
D12=RiskBernoulli(B12,RiskName(A12))Design change: a Bernoulli with probability B12 (0.35)
D13=RiskBernoulli(B13,RiskName(A13))Supplier delay: a Bernoulli with probability B13 (0.2)
D14=RiskBernoulli(B14,RiskName(A14))Severe weather: a Bernoulli with probability B14 (0.3)
Demonstrations!B3=RiskNormal(100,10)*1.1a Normal with mean 100 and sd 10, then multiply the draw by 1.1; demonstration only, not used by the estimate
Demonstrations!B4=RiskNormal(Estimate!C3*1.1,10)a Normal with mean Estimate!C3*1.1 (132) and sd 10; demonstration only, not used by the estimate

The same import reads the rest of the model:

Formulas that do not convert are listed too. All 3 on the second sheet come with the reason the import gives, and each has a way forward:

What the import does not convert, with its reason, on the workbook’s “Demonstrations” sheet
FormulaReason givenWhat to do
=RiskBinomial(1,0.3)*RiskTriang(20,40,80)multiple distributions in one formula are not converted; give each distribution its own input cellSplit it: one cell =RiskBernoulli(0.3) for whether the risk occurs, one =RiskTriang(20,40,80) for its impact, and multiply them in a third, as the estimate’s risk events do.
=RISKCOMPOUND(RiskPoisson(3),RiskLognorm(10,3))RISKCOMPOUND has no exact xellstorm equivalentxellstorm has no compound distribution. Model the count and the sizes in cells of their own, or leave the cell out of the model.
=RISKPERTALT(10%,90,"m.likely",100,90%,130)RISKPERTALT has no exact xellstorm equivalentEnter the PERT’s min, most likely and max (RiskPert), or give the percentiles to RiskTrigen, which converts.

Running the converted model

Run with the imported setup and 5,000 trials, the average total cost is 2,784.7 (USD thousands), and the exact mean of the same distributions, the PERT means (min + 4 × most likely + max) / 6 plus each risk’s probability times its impact, is 2,784.7; the standard error of the simulated mean is 1.7. Structure and MEP reach a rank correlation of 0.60. The three budgets of the RiskSimtable, run as the base and two scenarios:

The imported model, run: chance the total cost exceeds each budget of the RiskSimtable (5,000 trials, USD thousands)
RunBudgetChance of going over
Base run (simulation 1)2,90017.7%
Simulation 23,0005.2%
Simulation 33,1000.7%

A larger budget is exceeded less often, and because the scenarios draw the same numbers as the base run, the differences between the rows come from the budget alone, not from sampling.

Will the results match the add-in?

The model is the same; the random numbers are not. Each rule of the import maps a function to the distribution it describes, with the parameters translated as the vendor documents them, and is tested against the equivalent scipy distribution; the script that makes the test data also checks each mapping’s mean against the vendor’s documented formula. So once every distribution of a workbook converts, its means and percentiles differ from the add-in’s by sampling noise, which shrinks as you run more trials: the standard error above is the size to expect for the mean.

Correlations are rank correlations, as @RISK and Analytic Solver define them, and xellstorm reaches the rank correlation asked for. How the draws are paired to reach it is each tool’s own, so a correlated model can differ a little more in the tails than sampling noise alone explains. The workbook itself is not changed: xellstorm reads the file, and your model still opens in the add-in.

What converts

What does not convert

Multiple distributions in one cell, a distribution inside another function or in a denominator, direct division of a distribution, and chains that require changing the order of arithmetic do not convert. For example, (RiskNormal(0,1)+5)*2 and RiskNormal(0,1)*2*3 are left with a reason. RiskNormal(0,1)*(1/C1) does convert when C1 gives a finite positive multiplier, because the formula explicitly calculates the reciprocal before multiplying. Multipliers that work out to zero or less, arguments that call functions or depend on random cells, functions with no exact equivalent (compound distributions, time-series functions, RiskPertAlt and the other two-shape percentile forms), ModelRisk’s U argument and copulas, and properties not in the table also remain unsupported. An unsupported add-in formula cannot be calculated by the engine; the compatibility check names it.

Supported functions

The tables are generated from the importer’s own rule list, so they are exactly what it converts. “Percentiles” marks the forms that give a distribution by its percentiles; † marks the functions that convert with numbers only. Under each distribution is its name in xellstorm specs.

Distribution functions the importer converts, by distribution († numbers only: the parameters are computed from the arguments)
Distribution (xellstorm name)@RISKModelRiskAnalytic Solver
Bernoulli
bern
RiskBernoulliVoseBernoulliPsiBernoulli
Beta
beta
RiskBeta
RiskBetaGeneral
RiskBetaSubj†
VoseBeta
VoseBeta4
VoseBetaSubj†
PsiBeta
PsiBetaGen
PsiBetaSubj†
Binomial
binom
RiskBinomialVoseBinomialPsiBinomial
Burr XII
burr12
RiskBurr12——
Cauchy
cauchy
RiskCauchy
Percentiles:
RiskCauchyAlt
RiskCauchyAltD
VoseCauchy—
Chi-squared
chi2
RiskChiSq
Percentiles:
RiskChiSqAlt
RiskChiSqAltD
VoseChiSqPsiChiSquare
Percentiles:
PsiChiSquareAlt
Chi, Maxwell
chi
—VoseChi
VoseMaxwell
—
Cumulative
cumul
RiskCumul
RiskCumulD†
VoseCumulA
VoseCumulD†
VoseOgive†
PsiCumul
Dagum (Burr III)
burr
RiskDagumVoseDagumPsiDagum
Discrete
custom
RiskDiscrete
RiskDUniform
VoseDiscrete
VoseDUniform
PsiDiscrete
PsiDisUniform
Exponential
expon
RiskExpon
Percentiles:
RiskExponAlt
RiskExponAltD
VoseExpon
VoseExponential
PsiExponential
Percentiles:
PsiExponentialAlt
Extreme value (max, Gumbel)
gumbel_r
RiskExtValue
Percentiles:
RiskExtValueAlt
RiskExtValueAltD
VoseExtValueMaxPsiMaxExtreme
Percentiles:
PsiMaxExtremeAlt
Extreme value (min)
gumbel_l
RiskExtValueMin
Percentiles:
RiskExtValueMinAlt
RiskExtValueMinAltD
—PsiMinExtreme
Percentiles:
PsiMinExtremeAlt
F
f
RiskFVoseFPsiFDist
Fatigue life (Birnbaum–Saunders)
fatiguelife
RiskFatigueLife
Percentiles:
RiskFatigueLifeAlt
RiskFatigueLifeAltD
VoseFatiguePsiFatigueLife
Percentiles:
PsiFatigueLifeAlt
Fréchet
invweibull
RiskFrechet
Percentiles:
RiskFrechetAlt
RiskFrechetAltD
—PsiFrechet
Percentiles:
PsiFrechetAlt
Gamma, Erlang
gamma
RiskGamma
RiskErlang
Percentiles:
RiskGammaAlt
RiskGammaAltD
VoseGamma
VoseErlang
PsiGamma
PsiErlang
Percentiles:
PsiGammaAlt
General (relative weights)
general
RiskGeneralVoseRelative—
Generalized Pareto
genpareto
—VoseGPD—
Histogram
histogram
RiskHistogrmVoseHistogramPsiHistogram
Hyperbolic secant
hypsecant
RiskHypSecant
Percentiles:
RiskHypSecantAlt
RiskHypSecantAltD
VoseHSPsiHypSecant
Hypergeometric
hypergeom
RiskHypergeoVoseHypergeoPsiHyperGeo
Integer uniform
randint
RiskIntUniformVoseIntUniform
VoseStepUniform†
PsiIntUniform
Inverse Gaussian
invgauss
RiskInvgauss
Percentiles:
RiskInvgaussAlt
RiskInvgaussAltD
VoseInvGaussPsiInvNormal
Johnson SB
johnsonsb
RiskJohnsonSBVoseJohnsonBPsiJohnsonSB
Johnson SU
johnsonsu
RiskJohnsonSUVoseJohnsonUPsiJohnsonSU
Kumaraswamy
kumaraswamy
RiskKumaraswamyVoseKumaraswamy
VoseKumaraswamy4
PsiKumaraswamy
Laplace
laplace
RiskLaplace
Percentiles:
RiskLaplaceAlt
RiskLaplaceAltD
VoseLaplace—
Lévy
levy
RiskLevy
Percentiles:
RiskLevyAlt
RiskLevyAltD
VoseLevyPsiLevy
Percentiles:
PsiLevyAlt
Log-logistic
fisk
RiskLogLogistic
Percentiles:
RiskLogLogisticAlt
RiskLogLogisticAltD
VoseLogLogisticPsiLogLogistic
Percentiles:
PsiLogLogisticAlt
Logistic
logistic
RiskLogistic
Percentiles:
RiskLogisticAlt
RiskLogisticAltD
VoseLogisticPsiLogistic
Percentiles:
PsiLogisticAlt
Lognormal
lognorm
RiskLognorm
RiskLognorm2
Percentiles:
RiskLognormAlt
RiskLognormAltD
VoseLognormal
VoseLognormalE
PsiLogNormal
PsiLognorm
PsiLognorm2
Percentiles:
PsiLogNormalAlt
Negative binomial, geometric
nbinom
RiskGeomet
RiskNegbin
VoseGeometric
VoseNegBin
VoseNegBinom
VosePolya†
PsiGeometric
PsiNegBinomial
Normal
norm
RiskNormal
RiskErf†
Percentiles:
RiskNormalAlt
RiskNormalAltD
VoseNormal
VoseErf†
PsiNormal
PsiErf†
Percentiles:
PsiNormalAlt
Pareto
pareto
RiskPareto
Percentiles:
RiskParetoAlt
RiskParetoAltD
VoseParetoPsiPareto
Percentiles:
PsiParetoAlt
Pareto II (Lomax)
lomax
RiskPareto2
Percentiles:
RiskPareto2Alt
RiskPareto2AltD
VosePareto2PsiPareto2
Percentiles:
PsiPareto2Alt
Pearson V (inverse gamma)
invgamma
RiskPearson5
Percentiles:
RiskPearson5Alt
RiskPearson5AltD
VosePearson5PsiPearson5
Percentiles:
PsiPearson5Alt
Pearson VI (beta prime)
betaprime
RiskPearson6VosePearson6PsiPearson6
PERT
pert
RiskPertVosePERT
VoseModPERT
PsiPert
Poisson
poiss
RiskPoissonVosePoissonPsiPoisson
Rayleigh
rayleigh
RiskRayleigh
Percentiles:
RiskRayleighAlt
RiskRayleighAltD
VoseRayleighPsiRayleigh
Percentiles:
PsiRayleighAlt
Reciprocal (log-uniform)
loguniform
RiskReciprocalVoseReciprocalPsiReciprocal
Student’s t
t
RiskStudent
Percentiles:
RiskStudentAlt
RiskStudentAltD
VoseStudent
VoseStudent3†
PsiStudent
Percentiles:
PsiStudentAlt
Triangular
triang
RiskTriangVoseTrianglePsiTriangular
Triangular from percentiles (Trigen)
trigen
RiskTrigen
Percentiles:
RiskTriangAlt
VoseTriangleAltPsiTriangGen
Uniform
unif
RiskUniform
Percentiles:
RiskUniformAlt
RiskUniformAltD
VoseUniformPsiUniform
Weibull
weibull_min
RiskWeibull
Percentiles:
RiskWeibullAlt
RiskWeibullAltD
VoseWeibull
VoseWeibull3
PsiWeibull
Percentiles:
PsiWeibullAlt
Excel’s own sampling formulas the importer converts († numbers only)
Formulaxellstorm
=NORM.INV(RAND(), mean, sd)norm (loc, scale)
=NORMINV(RAND(), mean, sd)norm (loc, scale)
=mean + sd*NORM.S.INV(RAND())norm (loc, scale)
=LOGNORM.INV(RAND(), mu, sigma)lognorm (mu, sigma)
=LOGINV(RAND(), mu, sigma)lognorm (mu, sigma)
=GAMMA.INV(RAND(), alpha, beta)gamma (a, scale)
=GAMMAINV(RAND(), alpha, beta)gamma (a, scale)
=BETA.INV(RAND(), alpha, beta)beta (a, b)
=BETA.INV(RAND(), alpha, beta, A, B)beta (a, b, min, max)
=BETAINV(RAND(), alpha, beta, A, B)beta (a, b, min, max)
=BINOM.INV(n, p, RAND())binom (n, p)
=CRITBINOM(n, p, RAND())binom (n, p)
=RANDBETWEEN(a, b)randint (min, max)
=a + (b - a)*RAND()unif (min, max)
=a + s*RAND()unif (loc, scale)
=RAND()unif
=IF(RAND() < p, 1, 0)bern (p)
=IF(RAND() < p, x, y)†custom (x, prob)
Property functions, markers and statistics the importer reads
FunctionAdd-inBecomes in xellstorm
RiskTruncate@RISKTruncation: truncate_min, truncate_max (before any shift)
RiskTruncate2@RISKTruncation: truncate_min, truncate_max of the shifted values (moved back by the shift)
RiskTruncateP@RISKTruncation: truncate_pmin, truncate_pmax (percentiles of the distribution)
RiskShift@RISKShift: shift
RiskName@RISKName: the input's name
RiskLock@RISKLock: a fixed value (RiskLock(v), or the RiskStatic value)
RiskCorrmat@RISKCorrelation: rank correlations between the inputs of one matrix
RiskDepC@RISKCorrelation: a rank correlation with the input of the same pair name
RiskIndepC@RISKCorrelation: a rank correlation with the input of the same pair name
RiskSimtable@RISKOne value per simulation: a fixed cell in the base run, one scenario per further simulation
RiskOutput@RISKOutput: an output, with the name it gives
VoseXBoundsModelRiskTruncation: truncate_min, truncate_max (before any shift)
VosePBoundsModelRiskTruncation: truncate_pmin, truncate_pmax (percentiles of the distribution)
VoseShiftModelRiskShift: shift
VoseInputModelRiskName: the input's name
VoseSimTableModelRiskOne value per simulation: a fixed cell in the base run, one scenario per further simulation
VoseOutputModelRiskOutput: an output, with the name it gives
PsiTruncateAnalytic SolverTruncation: type 1 (the default): truncate_min, truncate_max before any shift; -1: of the shifted values; 3: truncate_pmin, truncate_pmax
PsiTruncatePAnalytic SolverTruncation: truncate_pmin, truncate_pmax (percentiles of the distribution)
PsiShiftAnalytic SolverShift: shift
PsiNameAnalytic SolverName: the input's name
PsiCorrMatrixAnalytic SolverCorrelation: rank correlations between the inputs of one matrix
PsiCorrDepenAnalytic SolverCorrelation: a rank correlation with the input of the same pair name
PsiCorrIndepAnalytic SolverCorrelation: a rank correlation with the input of the same pair name
PsiSimParamAnalytic SolverOne value per simulation: a fixed cell in the base run, one scenario per further simulation
PsiOutputAnalytic SolverOutput: an output: the cell itself, or the cells it refers to
PsiSimOutputAnalytic SolverOutput: an output: the cell itself, or the cells it refers to
PsiMeanAnalytic SolverStatistic: the cell of its first argument becomes an output (as with every Psi statistic of an output)

Questions

Do I need @RISK, ModelRisk or Analytic Solver installed?

No. xellstorm reads the formulas from the .xlsx file itself and calculates the model with its own engine in your browser, without Excel or the add-in. Save .xls and .xlsb workbooks as .xlsx first.

Does xellstorm change my workbook?

No. The import turns the formulas into inputs of xellstorm’s own setup; the file on your computer is not written, so the model still opens and runs in the add-in.

What happens to a correlation matrix?

Inputs that share a RiskCorrmat or PsiCorrMatrix range get the rank correlations of the matrix, read from its cells when you import; RiskDepC and PsiCorrDepen pair an input with the one of the same name. Pairs that cannot be read (a matrix that is not square, a position outside it, a cell without a number) are named in the import’s notes, and an input that did not convert is listed with its reason and left out of its pairs. If the matrix is not a valid correlation matrix, xellstorm applies the nearest valid one, and the app shows it before the run.

What does a RiskSimtable become?

The first value holds the cell in the base run and each further value becomes a scenario, named Simulation 2, Simulation 3 and so on. Scenarios draw the same random numbers as the base run, so the differences between them come from the table’s values alone.

@RISK, ModelRisk and Analytic Solver are trademarks of their respective owners. xellstorm is not affiliated with them; their function names appear here only to say what xellstorm reads.

Related

xellstorm is a browser-based Monte Carlo simulation tool for Excel models: no add-in, and the workbook never leaves your computer.