Composable contract building blocks producing cash flows

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 expression is the specification. There is no separate description of what an instrument does. The way it is composed is the description.

The Primitives: A Complete Vocabulary

The entire universe of financial contracts can be built from a small set of primitives:

Primitive Meaning
ZeroA 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.

flowchart TD Expression["Contract
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
flowchart TD WhenNode["When expiry"] --> OrNode["Or: choose the better"] OrNode --> ScaleNode["Scale by spot minus strike"] OrNode --> ZeroNode["Zero"] ScaleNode --> OneNode["One currency unit"] style WhenNode fill:#ede7f6,stroke:#764ba2,stroke-width:2px style OrNode fill:#e7f3ff,stroke:#0066cc,stroke-width:2px style ScaleNode fill:#e7f3ff,stroke:#0066cc style ZeroNode fill:#f8f9fa,stroke:#6c757d style OneNode fill:#d1f2eb,stroke:#1abc9c,stroke-width:2px

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 codeNew instrument → new expression
Logic scattered across systemsValid by construction
Testing requires deep internal knowledgeEvaluation 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

LedgerVue

LedgerVue Team

LedgerVue is a comprehensive multi-asset portfolio management system designed for wealth managers and family offices. Our platform automates investment reporting across all asset classes, eliminating manual spreadsheet work with consolidated portfolio reporting and performance analytics.