Composing contracts:
an adventure in �nancial engineering
Copyright By PowCoder代写 加微信 powcoder
Functional pearl
Microsoft Research, Cambridge
LexiFi Technologies, Paris
Julian of Glasgow
Financial and insurance contracts do not sound like promis-
ing territory for functional programming and formal seman-
tics, but in fact we have discovered that insights from pro-
gramming languages bear directly on the complex subject
of describing and valuing a large class of contracts.
We introduce a combinator library that allows us to de-
scribe such contracts precisely, and a compositional denota-
tional semantics that says what such contracts are worth.
We sketch an implementation of our combinator library in
Haskell. Interestingly, lazy evaluation plays a crucial role.
1 Introduction
Consider the following �nancial contract, C: the right to
choose on 30 June 2000 between
D1 Both of:
D11 Receive $100 on 29 Jan 2001.
D12 Pay $105 on 1 Feb 2002.
D2 An option exercisable on 15 Dec 2000 to choose one of:
D21 Both of:
D211 Receive $100 on 29 Jan 2001.
D212 Pay $106 on 1 Feb 2002.
D22 Both of:
D221 Receive $100 on 29 Jan 2001.
D222 Pay $112 on 1 Feb 2003.
The details of this contract are not important, but it is a
simpli�ed but realistic example of the sort of contract that is
traded in �nancial derivative markets. What is important is
that complex contracts, such as C, are formed by combining
together simpler contracts, such as D1, which in turn are
formed from simpler contracts still, such as D11, D12.
At this point, any red-blooded functional programmer
should start to foam at the mouth, yelling \build a com-
binator library”. And indeed, that turns out to be not only
possible, but tremendously bene�cial.
The �nance industry has an enormous vocabulary of jargon
for typical combinations of �nancial contracts (swaps, fu-
tures, caps,
oors, swaptions, spreads, straddles, captions,
European options, American options, …the list goes on).
Treating each of these individually is like having a large
catalogue of prefabricated components. The trouble is that
someone will soon want a contract that is not in the cata-
If, instead, we could de�ne each of these contracts using
a �xed, precisely-speci�ed set of combinators, we would be
in a much better position than having a �xed catalogue.
For a start, it becomes much easier to describe new, unfore-
seen, contracts. Beyond that, we can systematically analyse,
and perform computations over these new contracts, because
they are described in terms of a �xed set of primitives.
The major thrust of this paper is to draw insights from the
study of functional programming to illuminate the world of
�nancial contracts. More speci�cally, our contributions are
the following:
� We de�ne a carefully-chosen set of combinators, and,
through an extended sequence of examples in Haskell,
we show that these combinators can indeed be used to
describe a wide variety of contracts (Section 3).
� Our combinators can be used to describe a contract, but
we also want to process a contract. Notably, we want to
be able to �nd the value of a contract. In Section 4 we
describe how to give an abstract valuation semantics to
our combinators. A fundamentally-important property
of this semantics is that it is compositional ; that is, the
value of a compound contract is given by combining
the values of its sub-contracts.
� We sketch an implementation of our valuation seman-
tics, using as an example a simple interest rate model
and its associated lattice (Section 5). Lazy evaluation
turns out to be tremendously important in translating
the compositional semantics into a modular implemen-
tation (Section 5.3).
Stated in this way, our work sounds like a perfectly rou-
tine application of the idea of using a functional language
Composing Contracts:
An Adventure in Financial Engineering
Permission to make digital or hard copies of all or part of this work for
personal or classroom use is granted without fee provided that copies
are not made or distributed for profit or commercial advantage and that
copies bear this notice and the full citation on the first page. To copy
otherwise, or republish, to post on servers or to redistribute to lists,
requires prior specific permission and/or a fee.
ICFP’00, Montreal, Canada.
Copyright 2000 ACM 1-58113-202-6/00/0009…$5.00.
Copyright 2000 ACM 1-58113-202-6/00/0009…$5.00.
c, d, u Contract
o Observable
t, s Date, time
k Currency
x Dimensionless real value
p Value process
v Random variable
Figure 1: Notational conventions
to de�ne a domain-speci�c combinator library, thereby ef-
fectively creating an application-speci�c programming lan-
guage. Such languages have been de�ned for parsers,
music, animations, hardware circuits, and many others
[van Deursen et al., 2000]. However, from the standpoint of
�nancial engineers, our language is truly radical: they ac-
knowledge that the lack of a precise way to describe complex
contracts is \the bane of our lives”1.
It has taken us a long time to boil down the immense soup
of actively-traded contracts into a reasonably small set of
combinators; but once that is done, new vistas open up,
because a single formal description can drive all manner of
automated processes. For example, we can generate sched-
ules for back-oÆce contract execution, perform risk analysis
optimisations, present contracts in new graphical ways (e.g.
decision trees), provide animated simulations, and so on.
This paper is addressed to a functional programming audi-
ence. We will introduce any �nancial jargon as we go.
2 Getting started
In this section we will informally introduce our notation for
contracts, and show how we can build more complicated con-
tracts out of simpler ones. We use the functional language
Haskell [ et al., 1999] throughout.
2.1 A simple contract
Consider the following simple contract, known to the indus-
try as zero-coupon discount bond : \receive $100 on 1st Jan-
uary 2010″. We can specify this contract, which we name
c1 :: Contract
c1 = zcb t1 100 GBP
Figure 1 summarises the notational conventions we use
throughout the paper for variables, such as c1 and t1 in
this de�nition.
The combinator zcb used in c1’s de�nition has the following
zcb :: Date -> Double -> Currency -> Contract
The �rst argument to zcb is a Date, which speci�es a partic-
ular moment in time (i.e. both date and time). We provide
a function, date, that converts a date expressed as a friendly
character string to a Date.
date :: String -> Date
The quote is from an informal response to a draft of our work
Now we can de�ne our date t1:
t1,t2 :: Date
t1 = date “1530GMT 1 Jan 2010”
t2 = date “1200GMT 1 Feb 2010″
We will sometimes need to subtract dates, to get a time
di�erence, and add a date and a time di�erence to get a
type Days = Double — A time difference
diff :: Date -> Date -> Days
add :: Date -> Days -> Date
We represent a time di�erence as a
oating-point number in
units of days (parts of days can be important).
2.2 Combining contracts
So zcb lets us build a simple contract. We can also combine
contracts to make bigger contracts. A good example of such
a combining form is and, whose type is:
and :: Contract -> Contract -> Contract
Using and we can de�ne c3, a contract that involves two
payments2:
c2,c3 :: Contract
c2 = zcb t2 200 GBP
c3 = c1 `and` c2
That is, the holder of contract c3 will bene�t from a payment
of $100 at time t1, and another payment of $200 at time
In general, the contracts we can describe are between two
parties, the holder of the contract, and the counter-party.
Notwithstanding Biblical advice (Acts 10.35), by default the
owner of a contract receives the payments, and makes the
choices, speci�ed in the contract. This situation can be re-
versed by the give combinator:
give :: Contract -> Contract
The contract give c is simply c with rights and obligations
reversed, a statement we will make precise in Section 4.2. In-
deed, when two parties agree on a contract, one acquires the
contract c, and the other simultaneously acquires (give c);
each is the other’s counter-party. For example, c4 is a con-
tract whose holder receives $100 at time t1, and pays $200
at time t2:
c4 = c1 `and` give c2
So far, each of our de�nitions has de�ned a new contract
(c1, c2, etc). It is also easy to de�ne a new combinator
(a function that builds a contract). For example, we could
de�ne andGive thus:
andGive :: Contract -> Contract -> Contract
andGive c d = c `and` give d
Now we can give an alternative de�nition of c4 (which we
built earlier):
c4 = c1 `andGive` c2
In Haskell, a function can be turned into an in�x operator by
enclosing it in back-quotes.
This ability to de�ne new combinators, and use them just
as if they were built in, is quite routine for functional pro-
grammers, but not for �nancial engineers.
3 Building contracts
We have now completed our informal introduction. In this
section we will give the full set of primitives, and show how a
wide variety of other contracts can be built using them. For
reference, Figure 2 gives the primitive combinators over con-
tracts; we will introduce these primitives as we need them.
3.1 Acquisition date and horizon
Figure 2 gives an English-language, but quite precise, de-
scription of each combinator. To do so, it uses two technical
terms: acquisition date, and horizon. We begin by intro-
ducing them brie
Our language describes what a contract is. However, what
the consequences for the holder of the contract depends on
the date at which the contract is acquired, its acquisition
date. (By \consequences for the holder” we mean the rights
and obligations that the contract confers on the holder of
a contract.) For example, the contract \receive $100 on 1
Jan 2000 and receive $100 on 1 Jan 2001″ is worth a lot less
if acquired after 1 Jan 2000, because any rights and obliga-
tions that fall due before the acquisition date are simply
discarded.
The second fundamental concept is that of a contract’s hori-
zon, or expiry date: the horizon, or expiry date, of a contract
is the latest date at which it can be acquired. A contract’s
horizon may be �nite or in�nite. The horizon of a contract is
completely speci�ed by the contract itself: given a contract,
we can easily work out its horizon using the de�nitions in
Figure 2. Note carefully, though, that a contract’s rights
and obligations may, in principle, extend well beyond its
horizon. For example, consider the contract \the right to
decide on or before 1 Jan 2001 whether to have contract
C”. This sort of contract is called an option. Its horizon
is 1 Jan 2001 | it cannot be acquired after that date |
but if one acquires it before then, the underlying contract
C may (indeed, typically will) have consequences extending
well beyond 1 Jan 2001.
To reiterate, the horizon of a contract is a property of the
contract, while the acquisition date is not.
3.2 Discount bonds
Earlier, we described the zero-coupon discount bond: \re-
ceive $100 at time t1″ (Section 2.1). At that time we as-
sumed that zcb was a primitive combinator, but in fact it
isn’t. It is obtained by composing no fewer than four more
primitive combinators. We begin with the one combinator:
c5 = one GBP
Figure 2 gives a careful, albeit informal, de�nition of one:
if you acquire (one GBP), you immediately receive $1. The
contract has an in�nite horizon; that is, there is no restric-
tion on when you can acquire this contract.
But the bond we want pays $100 at t1, and no earlier,
regardless of when the bond itself is acquired. To obtain
this e�ect we use two other combinators, get and truncate,
c6 = get (truncate t1 (one GBP))
(truncate t c) is a contract that trims c’s horizon so that
it cannot be acquired any later than t. (get c) is a con-
tract that, when acquired, acquires the underlying contract
c at c’s horizon | that is, at the last possible moment |
regardless of when the composite contract (get c) is ac-
quired. The combination of the two is exactly the e�ect
we want, since the horizon of (truncate t1 (one GBP)) is
exactly t1. Like one, get and truncate are de�ned in Fig-
We are still not �nished. The bond we want pays $100
not $1. We use the combinator scaleK to \scale up” the
contract, thus:
c7 = scaleK 100 (get (truncate t1 (one GBP)))
We will de�ne scaleK shortly, in Section 3.3. It has the type
scaleK :: Double -> Contract -> Contract
To acquire (scaleK x c) is to acquire c, but all the pay-
ments and receipts in c are multiplied by x. So we can,
�nally, de�ne zcb correctly:
zcb :: Date -> Double -> Currency -> Contract
zcb t x k = scaleK x (get (truncate t (one k)))
This de�nition of zcb e�ectively extends our repertoire of
combinators, just as andGive did in Section 2.2, only more
usefully. We will continually extend our library of combina-
tors in this way.
Why did we go to the trouble of de�ning zcb in terms of
four combinators, rather than making it primitive? Because
it turns out that scaleK, get, truncate, and one are all in-
dependently useful. Each embodies a distinct piece of func-
tionality, and by separating them we signi�cantly simplify
the semantics and enrich the algebra of contracts (Section 4).
The combinators we present are the result of an extended,
iterative process of re�nement, leading to an interlocking
set of decisions | programming language designers will be
quite familiar with this process.
3.3 Observables and scaling
A real contract often mentions quantities that are to be mea-
sured on a particular date. For example, a contract might
say \receive an amount in dollars equal to the noon Centi-
grade temperature in Los Angeles”; or \pay an amount in
pounds sterling equal to the 3-month LIBOR spot rate3 mul-
tiplied by 100″. We use the term observable for an objective,
but perhaps time-varying, quantity. By \objective” we mean
that at any particular time the observable has a value that
both parties to the contract will agree. The temperature in
Los Angeles can be objectively measured; but the value to
me of insuring my house is subjective, and is not an observ-
able. Observables are thus a di�erent \kind of thing” from
contracts, so we give them a di�erent type:
The LIBOR spot rate is published daily in the �nancial press. For
present purposes it does not matter what it means; all that matters
is that it is an observable quantity.
zero :: Contract
zero is a contract that may be acquired at any
time. It has no rights and no obligations, and
has an in�nite horizon. (Section 3.4.)
one :: Currency -> Contract
(one k) is a contract that immediately pays the
holder one unit of the currency k. The contract
has an in�nite horizon. (Section 3.2.)
give :: Contract -> Contract
To acquire (give c) is to acquire all c’s rights
as obligations, and vice versa. Note that for a
bilateral contract q between parties A and B, A
acquiring q implies that B acquires (give q).
(Section 2.2.)
and :: Contract -> Contract -> Contract
If you acquire (c1 `and` c2) then you immedi-
ately acquire both c1 (unless it has expired) and
c2 (unless it has expired). The composite con-
tract expires when both c1 and c2 expire. (Sec-
tion 2.2.)
or :: Contract -> Contract -> Contract
If you acquire (c1 `or` c2) you must immedi-
ately acquire either c1 or c2 (but not both). If
either has expired, that one cannot be chosen.
When both have expired, the compound contract
expires. (Section 3.4.)
truncate :: Date -> Contract -> Contract
(truncate t c) is exactly like c except that it
expires at the earlier of t and the horizon of c.
Notice that truncate limits only the possible ac-
quisition date of c; it does not truncate c’s rights
and obligations, which may extend well beyond
t. (Section 3.4.)
then :: Contract -> Contract -> Contract
If you acquire (c1 `then` c2) and c1 has not
expired, then you acquire c1. If c1 has expired,
but c2 has not, you acquire c2. The compound
contract expires when both c1 and c2 expire.
(Section 3.5.)
scale :: Obs Double -> Contract -> Contract
If you acquire (scale o c), then you acquire c
at the same moment, except that all the rights
and obligations of c are multiplied by the value
of the observable o at the moment of acquisition.
(Section 3.3.)
get :: Contract -> Contract
If you acquire (get c) then you must acquire c
at c’s expiry date. The compound contract ex-
pires at the same moment that c expires. (Sec-
tion 3.2.)
anytime :: Contract -> Contract
If you acquire (anytime c) you must acquire c,
but you can do so at any time between the acqui-
sition of (anytime c) and the expiry of c. The
compound contract expires when c does. (Sec-
tion 3.5.)
Figure 2: Primitives for de�ning contracts
noonTempInLA :: Obs Double
libor3m :: Obs Double
In general, a value of type Obs d represents a time-varying
quantity of type d.
In the previous section we used scaleK to scale a contract
by a �xed quantity. The primitive combinator scale scales
a contract by a time-varying value, that is, by an observable:
scale :: Obs Double -> Contract -> Contract
With the aid of scale we can de�ne the (strange but re-
alistic) contract \receive an amount in dollars equal to the
noon Centigrade temperature in Los Angeles”:
c8 = scale noonTempInLA (one USD)
Again, we have to be very precise in our de�nitions. Exactly
when is the noon temperature in LA sampled? Answer (in
Figure 2): when you acquire (scale o c) you immediately
acquire c, scaling all the payments and receipts in c by the
value of the observable o sampled at the moment of acquisi-
tion. So we sample the observable at a single, well-de�ned
moment (the acquisition date) and then use that single num-
ber to scale the subsequent payments and receipts in c.
A very useful observable is one that has the same value at
every time:
konst :: a -> Obs a
With its aid we can de�ne scaleK:
scaleK :: Double -> Contract -> Contract
scaleK x c = scale (konst x) c
Any arithmetic combination of observables is also an observ-
able. For example, we may write:
ntLAinKelvin :: Obs Double
ntLAinKelvin = noonTempInLA + konst 373
We can use the addition operator, (+), to add two observ-
ables, because observables are an instance of the Num class4,
which has operations for addition, subtraction, multiplica-
tion, and so on:
instance Num a => Num (Obs a)
(Readers who are unfamiliar with Haskell’s type classes need
not worry | all we need is that we can employ the usual
arithmetic operators for observables.) These observables
and their operations are, of course, reminiscent of Fran’s
behaviours [Elliott and Hudak, 1997]. Like Fran, we pro-
vide combinators for lifting functions to the observable level,
lift, lift2, etc. Figure 3 gives the primitive combinators
over observables.
And indeed all the other numeric classes, such as Real,
Fractional, etc
konst :: a -> Obs a
(konst x) is an observable that has value x at
lift :: (a -> b) -> Obs a -> Obs b
(lift f o) is the observable whose value is the
result of applying f to the value of the observable
lift2 :: (a->b->c) -> Obs a -> Obs b -> Obs c
(lift2 f o1 o2) is the observable whose value
is the result of applying f to the values of the
observables o1 and o2.
instance Num a => Num (Obs a)
All numeric operations lift to the Obs type. The
implementation is simple, using lift and lift2.
time :: Date -> Obs Days
The value of the observable (time t) at time s
is the number of days between s and t, positive
if s is later than t.
There may be an arbitrary number of other primitive
observables provided by a particular implementation.
For example:
libor :: Currency -> Days -> Days -> Obs Double
(libor k m1 m2) is an observable equal, at any
time t, to the quoted forward (actuarial) rate in
currency k over the time interval t `add` m1 to
t `add` m2.
Figure 3: Primitives over observables
3.4 European options
Much of the subtlety in
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com