Macroeconomic scenario simulation framework
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.
