DECCF · Cash Flow Modeler and Calculator

Result format

run() returns a frozen JavaScript object. JSON.stringify(result) calls result.toJSON() automatically. Hash fields are not included.

Serialized top-level fields

  • results_version: the current format version, 0.24.
  • engine: engine name and version.
  • warnings: currently always an empty array.
  • inputs.preconditions: declared preconditions with name, shape, type, value, and origin. Curve preconditions also include the effective series.points and series.interpolation. The field is omitted if the model has no preconditions. The reporting currency is selected in the model or through the run() options.
  • deterministic: status, metrics, time series, annual rollup, optional labeled category hierarchy, account postings, and optional state transitions or journal entries.
  • scenarios: not_run with an empty summary list.
  • monte_carlo: not_run, zero trials, and empty summaries.
  • graph.entities: symbol, family, and optional parent.
  • graph.agreements: each agreement's subject and parties by role.
  • graph.accounts: account name, side (owed or due), optional type (asset, liability, equity, income, expense, or transfer), owner, and category. Labeled account categories also include category_label.
  • statements.statements and slices: empty collections.
  • timings: measured durations for preparation, the main run, metrics, result construction, and the full call.

These fields describe an ordinary run() result. They do not mean statements, slices, scenario aggregation, or Monte Carlo were run. runScenarios() and runMonteCarlo() return separate JavaScript values.

Runtime timings

timings uses integer microsecond ticks from the monotonic performance.now() clock. mainTicks includes model preparation and the period-by-period calculation; setupTicks and simulationTicks show those parts separately. resultConstructionTicks covers assembling the output, including its metric calculations. totalTicks measures the complete run() call, and totalMs reports the same duration in milliseconds. These measured values vary by device and load and do not affect the model's calculations.

Metric durations appear under timings.metrics. engine.steps includes built-in metrics such as model.total, model.npv, model.irr, and model.wal. model.steps lists each metric declared directly on the model. domainPacks groups each pack-provided metric by pack name. Every group has a totalTicks, and metrics.totalTicks sums all of these metric calculation steps.

Each item returned by runScenarios() includes its own result timings. Scenario results may be ordinary run results or Monte Carlo summaries when trials and seed are supplied. The returned array also has a timings property with scenario-by-scenario measurements and totals, including total milliseconds. When serializing the scenario array, include that property explicitly because JSON array serialization omits custom array properties: JSON.stringify({ scenarios, timings: scenarios.timings }). runMonteCarlo() returns timings for its full call and for each trial, including total metric time and summary construction time.

Deterministic metrics

deterministic.metrics contains model.total, model.npv, model.irr, model.wal_years, and run.periods_per_year. If supplied, the discount rate is also present as run.annual_discount_rate. Custom model metrics use the key metric.<name>; callbacks that return undefined are omitted. Each custom metric also has a time series at deterministic.series["metric.<name>"]. That series includes its owner, calculation window length, output frequency, annual aggregation rule, fiscal-year start month, and optional display label and unit.

Money values serialize as { amount, currency }; scalar metrics remain numbers. irr can be null. The serialized weighted average life metric is named model.wal_years.

Time series

Each series has an index with calendar, start, periods, and values. Metric series use the declared periodLength and frequency in model periods; periods without an emitted value contain null. annual_rollup.series publishes model metrics using their annualAggregation rule and fiscal year. Its metric indexes use calendar: "fiscal-year" and include display-ready periodLabels such as FY 2025/26. Company metrics can therefore use different fiscal periods in the same result. Serialized monetary values use { amount, currency }; field series are numeric. Common series names include:

  • flow.<name> and option.<name>
  • model.net_cash_flow
  • metric.<name>
  • entity.<family>.<name>.net_cash_flow
  • <family>.<entity>.<field>
  • Component outputs are available through result.component(reference); repeated outputs are keyed by their stable row IDs.

Account balances are published separately as account.<name>.balance; they are not included in model net cashflow. For posting cashflows, net cashflow comes from the cash account's signed postings. The engine uses cashAccount, or infers it when exactly one posted account has type asset. A posting cashflow also inherits the owner when all posted accounts share one. If a flow has more than one category, its series attribute category is null; use result.category(ref) to summarize its posted movements. Category summaries include both categories on basic cashflows and those inherited from posted accounts, including balance-sheet accounts. Annual rollups sum flows, options, and model net cashflow; component calculation outputs are reported separately and are not counted as cashflows.

deterministic.categories lists labeled category paths used by accounts and cashflows. Each entry contains path, label, and an optional parent_path. Account postings include category_label when the category reference has a label. A category such as business.class_1_assets.group_11_byggnader_och_mark can therefore be shown by a report using only the returned result; its result.category(ref) value includes all descendant account categories.

JavaScript accessors

Compatibility fields and methods are available directly on the result:

  • model, currency, dates, metrics, series, transitions, events
  • flow(ref), option(ref), field(ref), account(ref), state(entityRef), category(categoryRef), entity(entityRef), component(componentRef)
  • toJSON()

Accessors take declaration references, not string names. metrics includes total, npv, irr, and wal. category() sums a category path and its descendants; for postings, signs follow the account's reporting type. entity() sums cashflows and options for the entity and descendants. account(ref) returns period-ending balances, while the serialized account series uses account.<name>.balance. component(ref) returns its declared outputs; repeated components return an items record keyed by stable input row IDs.

flow(ref), option(ref), field(ref), and compatibility series expose numeric arrays in the model currency or field units. Use deterministic.series when you need a currency object for each value.