Why Contracts Matter in Financial Software
In 2000, Simon Peyton Jones and Jean-Marc Eber published a paper that should have transformed how the financial industry builds software.
“Composing Contracts: An Adventure in Financial Engineering” showed that financial instruments — bonds, swaps, options, even exotic derivatives — can be modelled as composable expressions, built from a small set of primitives.
Twenty-five years later, most financial software is still built on rigid relational schemas:
- Separate tables for bonds, swaps, options
- Instrument-specific columns
- Fragile validation logic
- Schema migrations for every new product variant
The industry largely ignored this research. Yet for those who adopted it, this approach remains the only sane way to model this domain.
The Core Idea
Every financial instrument — no matter how complex — can be expressed as a composition of simple building blocks. Those building blocks compose naturally and easily, can be evaluated mechanically, and produce cash flows directly.
The Primitives: A Complete Vocabulary
The entire universe of financial contracts can be built from a small set of primitives:
| Primitive | Meaning |
|---|---|
Zero | A contract worth nothing |
One(currency) | Receive 1 unit of currency immediately |
Give(contract) | Reverse all cash flows |
And(c1, c2) | Hold both contracts |
Or(c1, c2) | Choose the better of two contracts |
Scale(amount, contract) | Multiply all cash flows |
When(date, contract) | Acquire the contract at a specific date |
Anytime(date, contract) | Exercise any time until a date |
That’s it.
Observables: Making Contracts Reactive
Some values are only known in the future. These are observables. Observables allow contingent decisions — contracts whose behaviour depends on market conditions at evaluation time.
We can define an abstraction for this, Obs, which represents an external value such as a market reference: the price of an underlying, a benchmark rate, and so on. This allows us to do basic arithmetic on them, for example price - strike.
From Expression to Cash Flows
Evaluation is purely mechanical. Although the original paper used Haskell, an object-oriented language like C# can achieve the same result using the Visitor pattern: contracts are defined as immutable data structures, and evaluating an instrument is a tree traversal. The visitor walks the expression tree, resolves observables using market data, applies the composition rules, and emits cash flows.
expression tree"] --> Visitor["Visitor
walks the tree"] MarketData["Market data"] --> Observables["Observables
resolved"] Observables --> Visitor Visitor --> Composition["Composition
rules applied"] Composition --> CashFlows["Cash flows
emitted"] style Expression fill:#ede7f6,stroke:#764ba2,stroke-width:2px style MarketData fill:#fff3e0,stroke:#ff9800 style Observables fill:#fff3e0,stroke:#ff9800 style Visitor fill:#e7f3ff,stroke:#0066cc,stroke-width:2px style Composition fill:#e7f3ff,stroke:#0066cc style CashFlows fill:#d1f2eb,stroke:#1abc9c,stroke-width:2px
Evaluation of instrument cash flows
There is no hidden logic. No “special case” pricing code. The expression is the truth.
Example: A European Call Option
A European call gives the right — but not the obligation — to buy an asset at a strike price on expiry. Conceptually:
When expiry:
choose the better of
(spot - strike)
zero
The European call as an expression tree
- If spot > strike, exercise.
- If spot ≤ strike, do nothing.
The familiar payoff max(spot - strike, 0) emerges naturally. We didn’t code it. It falls out of the algebra.
Contingent Decisions in Practice
This same pattern models other instruments. Take a convertible bond:
- If stock > threshold, convert to shares.
- Otherwise, receive the bond cash flows.
No bespoke instrument tables or classes, just an expression composing some primitives.
Why This Matters
| Traditional financial software | Algebraic contracts |
|---|---|
| New instrument → new code | New instrument → new expression |
| Logic scattered across systems | Valid by construction |
| Testing requires deep internal knowledge | Evaluation is the test |
Final Thought
Any financial contract can be expressed using a small set of primitives and an algebra for combining them. The benefit is that a new instrument becomes a new expression rather than new code: valid by construction, and evaluated mechanically into its cash flows. Although this insight was published in 2000, it is still mostly ignored.
References
- Simon Peyton Jones and Jean-Marc Eber, Composing Contracts: An Adventure in Financial Engineering (2000)
- Simon Peyton Jones, video lecture on Composing Contracts