Complexa Labs
Back to experience
Financial services · Financial consultancy

Macroeconomic scenario simulation framework

Quantitative engineer · 2025

The problem

The consultancy ran scenario-planning exercises for institutional clients across multiple planning horizons — short-term tactical, medium-term strategic, long-term structural. Each scenario involved 500+ interdependent macroeconomic variables linked by accounting identities, equilibrium constraints, and policy levers. The existing tooling could simulate forward paths but could not optimise them: it could not answer "under these constraints, what is the best feasible path for variable X?"

Approach

Framing as non-linear constrained optimisation

Each scenario was re-cast as a non-linear constrained optimisation problem over the joint trajectory of the 500+ variables across the simulation horizon. Constraints encoded the accounting identities, range bounds on policy levers, and equilibrium conditions; the objective encoded the client's planning preference (smoothing, target-hitting, risk-weighted cost).

Multi-solver architecture

No single solver handles every scenario well — gradient-based methods stall on non-differentiable cost surfaces, evolutionary methods are slow on smooth-but-large problems, and pure global searches are infeasible at this dimensionality. I built a solver-routing layer over three complementary engines:

  • IPOPT for smooth, gradient-tractable formulations — the workhorse for most production scenarios. Sparse Jacobians and warm-starts kept it tractable at the 500-variable scale.
  • CMA-ES for non-smooth or noisy objective landscapes where local gradients lie about the true descent direction.
  • Differential evolution for global exploration when local minima were a known risk — typically the first pass on a new scenario class, before warm-starting IPOPT.

Engineering for the analyst workflow

The framework was used directly by economists, not just by engineers. That shaped the interface: scenarios were declared in structured configuration rather than code; solver choice was automatic with sensible escape hatches; convergence diagnostics and constraint violations surfaced in human-readable form. The point was to let domain experts run rigorous optimisation without writing solver code.

Outcome

The consultancy went from forward-only simulation to genuine constrained-optimisation scenario design — supporting more sophisticated client engagements where the question was "what is achievable" rather than "what happens if".

Stack

Python · IPOPT · CMA-ES · scipy.optimize (differential evolution) · NumPy · sparse Jacobian tooling.