Skip to content

Client work · 2025 · Systems engineering

Actuarial Simulation Engine

A desktop simulation engine that translates C# actuarial formulas to FIS Prophet and runs large workspaces without leaving the machine.

SQLite journal mode
WAL
Vectorised inner loop
SIMD
Variable resolution
2-level

Client engagement. Business specifics are kept generic; everything below describes work that is mine to describe.

The problem

Actuarial teams model products as thousands of interdependent variables, then override slices of them per workspace. Doing this in spreadsheets is slow and untraceable; doing it in Prophet means hand-translating formulas. The engine had to hold the variable model, run simulations locally, and emit Prophet-compatible formulas.

Constraints

  • Runs entirely on a workstation — no server, no cloud, data never leaves the box
  • Overrides must be resolvable per workspace without duplicating the product model
  • Runs are long; a 2x speedup is the difference between a coffee break and a lost afternoon

Architecture

01 UI

  • WinUI 3
  • Virtualised variable grid
  • Run progress + cancellation

02 Engine

  • Simulation core
  • Parallel run partitioning
  • SIMD numeric kernels

03 Model

  • Product variables
  • Workspace overrides
  • Resolution cache

04 Storage

  • SQLite (WAL)
  • Batched transactions
  • Local-only persistence
Actuarial Simulation Engine — layers top to bottom, each depending only on the one below.
  • C#
  • WinUI 3
  • SQLite
  • .NET
  • SIMD intrinsics

Key decision

Product/workspace override resolution instead of copied models

The naive model copies a product's full variable set into each workspace so it can be edited. That multiplies storage, and a change to the product never reaches its workspaces. Instead workspaces store only overrides and resolve against the product at read time — one lookup layer, one source of truth. Changing a product variable propagates to every workspace that hasn't explicitly overridden it.

What it cost

Every read pays a resolution cost, which is why the hot path is cached per run and the whole layer is fronted by batched transactions. Worth it: correctness bugs from divergent copies are far more expensive than lookups.

Outcome

  • Performance work was measured, not guessed: WAL mode for concurrent reads during writes, batched transactions to cut fsync pressure, parallelism across run partitions, SIMD in the numeric inner loop.
  • The C#-to-Prophet formula translator removes a manual re-entry step that was the main source of modelling errors.
  • Client engagement — specifics of the actuarial models are kept generic here.

Screens

ScreenSimulation engine workspace showing product variables and overrides
ScreenSimulation run view with progress and performance statistics