Skip to content

Commit 74b0b31

Browse files
WIP revisit valuation semantics
1 parent 456df75 commit 74b0b31

File tree

6 files changed

+708
-184
lines changed

6 files changed

+708
-184
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
-- Copyright (c) 2022 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2+
-- SPDX-License-Identifier: Apache-2.0
3+
4+
module ContingentClaims.Valuation.AcquisitionTime
5+
( AcquisitionTime(..)
6+
, beforeOrAtToday
7+
, extend
8+
, isNever
9+
) where
10+
11+
import ContingentClaims.Core.Claim (Inequality(..))
12+
import Prelude hiding (Time, sequence, mapA, const)
13+
14+
-- | Acquisition time of a contract in the context of the valuation semantics.
15+
-- It is either a deterministic time (`Time t`) or it is defined based on a list of `Inequality`.
16+
-- For inequalities [i_1, i_2, ..., i_N], the acquisition time is defined as the first instant `t` for which there exist times `t_1 ≤ t_2 ≤ ... ≤ t_N ≤ t` such that `t_k` verifies `i_k` for each `k`.
17+
-- In both cases, the time `t` is a stopping time in the mathematical sense.
18+
data AcquisitionTime t x o
19+
= Time t
20+
-- ^ Acquisition at time `t`.
21+
| AtInequality { inequalities : [Inequality t x o] }
22+
-- ^ Acquisition when inequalities are verified. The order of the inequalities matters (see definition above).
23+
| Never
24+
-- ^ Acquisition never happens.
25+
deriving (Eq,Show)
26+
27+
-- | Given an inequality and an acquisition time τ1, it returns the acquisition time τ2 corresponding to the first instant such that
28+
-- - the inequality is verified
29+
-- - τ2 ≥ τ1
30+
-- The name `extend` comes from the fact that we are extending the set of inequality constraints that need to be verified.
31+
extend : (Ord t) => Inequality t x o -> AcquisitionTime t x o -> AcquisitionTime t x o
32+
extend _ Never = Never
33+
extend (TimeGte s) (Time t) = Time $ max s t
34+
extend (TimeLte s) (Time t) | s >= t = Time t
35+
extend (TimeLte s) (Time t) = Never
36+
extend ineq@(Lte _) (Time t) = AtInequality [TimeGte t, ineq]
37+
extend ineq (AtInequality ineqs) = AtInequality $ ineqs <> [ineq]
38+
39+
-- | Checks if an acquisition time falls before or at the today date.
40+
-- `None` is returned if the acquisition time is unknown.
41+
beforeOrAtToday : (Ord t) => t -> AcquisitionTime t x a -> Optional Bool
42+
beforeOrAtToday _ Never = Some False
43+
beforeOrAtToday today (Time s) = Some $ s <= today
44+
beforeOrAtToday today (AtInequality _) = None
45+
46+
-- | Checks if an acquisition time is `Never`.
47+
-- This is used to avoid requiring the (Eq o) constraint.
48+
isNever : AcquisitionTime t x a -> Bool
49+
isNever Never = True
50+
isNever _ = False
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
-- Copyright (c) 2022 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
2+
-- SPDX-License-Identifier: Apache-2.0
3+
4+
module ContingentClaims.Valuation.Expression (
5+
Expr(..),
6+
ExprF(..),
7+
simplify
8+
) where
9+
10+
import ContingentClaims.Core.Claim (Inequality(..))
11+
import ContingentClaims.Valuation.AcquisitionTime(AcquisitionTime(..))
12+
import DA.Foldable
13+
import DA.Traversable
14+
import Daml.Control.Recursion
15+
import Prelude hiding (Time, sequence, mapA, const)
16+
17+
-- | Represents an algebraic expression of a t-adapted stochastic process.
18+
-- t : time parameter.
19+
-- x : state parameter, typically Decimal (our best approximation of real numbers).
20+
-- o : reference used to identify observables.
21+
-- b : type describing elementary processes.
22+
data Expr t x o b
23+
= Const x
24+
-- ^ A constant process.
25+
| Proc { name : b }
26+
-- ^ An elementary process which we cannot decompose further.
27+
-- | Sup { lowerBound: t, tau: t, rv : Expr t }
28+
-- -- ^ Sup, needs to be reworked using feasible exercise strategies.
29+
| Sum [Expr t x o b]
30+
-- ^ Sum process.
31+
| Neg (Expr t x o b)
32+
-- ^ Negation process.
33+
| Mul (Expr t x o b, Expr t x o b)
34+
-- ^ Multiplication of two processes (`p1 * p2`).
35+
| Inv (Expr t x o b)
36+
-- ^ Inverse of a process (`1 / p`).
37+
| Max [Expr t x o b]
38+
-- ^ Maximum process.
39+
| I (Inequality t x o)
40+
-- ^ Indicator function. I(p) is 1 if p(t) = True, False otherwise, where
41+
-- `p` is the boolean process corresponding to the provided inequality.
42+
-- Specifically, this means
43+
-- - for `o1 ≤ o2`, `p = υ(o1) ≤ υ(o2)`
44+
-- - for `TimeGte t`, `p(s) = s ≥ t`
45+
-- - for `TimeLte t`, `p(s) = s ≤ t`
46+
| E { process : Expr t x o b, time : AcquisitionTime t x o, filtration : AcquisitionTime t x o }
47+
-- ^ Conditional expectation of `process(time)` conditioned on the filtration F_`t`.
48+
-- | Snell { process : Expr t x o b, time : AcquisitionTime t x o, predicate : Inequality t x o}
49+
-- -- ^ Snell envelope of a stochastic process.
50+
-- -- We need the predicate to identify the feasible region
51+
-- -- I feel that we need the acquisition time to identify the conditional filtration, but it might not be needed.
52+
-- | Absorb { process : Expr t x o b, time : AcquisitionTime t x o, predicate : Inequality t x o}
53+
-- -- ^ Absorb primitive.
54+
-- -- It feels that absorb hides an expectation, but I need to write this down in formulas for better understanding.
55+
-- In order to write until valuation explicitly, we need to introduce a new class of boolean processes, namely those that we start observing at a time tau and have never been true since (we can then use an indicator function to transform it to a real process)
56+
-- We can use the absorb primitive to cover this case, which we can then distribute. across the other primitives.
57+
deriving (Eq,Show)
58+
59+
-- | Base functor for `Expr`.
60+
data ExprF t x o b c
61+
= ConstF x
62+
| ProcF { name : b }
63+
-- | Sup { lowerBound: t, tau: t, rv : Expr t }
64+
| SumF [c]
65+
| NegF c
66+
| MulF { lhs : c, rhs : c }
67+
| InvF c
68+
| MaxF [c]
69+
| I_F (Inequality t x o)
70+
| E_F { process : c, time : AcquisitionTime t x o, filtration : AcquisitionTime t x o }
71+
deriving (Functor)
72+
73+
instance Recursive (Expr t x o b) (ExprF t x o b) where
74+
project (Const d) = ConstF d
75+
project Proc{..} = ProcF with ..
76+
-- project Sup{..} = SupF with ..
77+
project (Sum xs) = SumF xs
78+
project (Neg x) = NegF x
79+
project (Mul (x,x')) = MulF x x'
80+
project (Inv x) = InvF x
81+
project (Max xs) = MaxF xs
82+
project (I x) = I_F x
83+
project E{..} = E_F with ..
84+
85+
instance Corecursive (Expr t x o b) (ExprF t x o b) where
86+
embed (ConstF d) = Const d
87+
embed ProcF{..} = Proc with ..
88+
-- embed SupF{..} = Sup with ..
89+
embed (SumF xs) = Sum xs
90+
embed (NegF x) = Neg x
91+
embed (MulF x x') = Mul (x, x')
92+
embed (InvF x) = Inv x
93+
embed (MaxF xs) = Max xs
94+
embed (I_F x) = I x
95+
embed E_F{..} = E with ..
96+
97+
instance Foldable (ExprF t x o b) where
98+
foldMap f (ConstF _) = mempty
99+
foldMap f (ProcF _) = mempty
100+
-- foldMap f (SupF _ _ x) = f x
101+
foldMap f (SumF xs) = foldMap f xs
102+
foldMap f (NegF x) = f x
103+
foldMap f (MulF x x') = f x <> f x'
104+
foldMap f (InvF x) = f x
105+
foldMap f (MaxF xs) = foldMap f xs
106+
foldMap f (I_F _) = mempty
107+
foldMap f (E_F x _ _) = f x
108+
109+
instance Traversable (ExprF t x o b) where
110+
sequence (ConstF d) = pure $ ConstF d
111+
sequence (ProcF x) = pure $ ProcF x
112+
-- sequence (SupF t τ fa) = SupF t τ <$> fa
113+
sequence (SumF [fa]) = (\a -> SumF [a]) <$> fa
114+
sequence (SumF (fa :: fas)) = s <$> fa <*> sequence fas
115+
where s a as = SumF (a :: as)
116+
sequence (SumF []) = error "Traversable ExprF: sequence empty SumF"
117+
sequence (NegF fa) = NegF <$> fa
118+
sequence (MulF fa fa') = MulF <$> fa <*> fa'
119+
sequence (InvF fa) = InvF <$> fa
120+
sequence (MaxF (fa :: fas)) = s <$> fa <*> sequence fas
121+
where s a as = MaxF (a :: as)
122+
sequence (MaxF []) = error "Traversable ExprF: sequence empty MaxF"
123+
sequence (I_F p) = pure $ I_F p
124+
sequence (E_F fa t f) = (\a -> E_F a t f) <$> fa
125+
126+
instance (Additive x) => Additive (Expr t x o b) where
127+
x + y = Sum [x, y]
128+
negate = Neg
129+
aunit = Const aunit
130+
131+
instance (Multiplicative x) => Multiplicative (Expr t x o b) where
132+
(*) = curry Mul
133+
munit = Const munit
134+
x ^ y | y > 0 = x * (x ^ pred y)
135+
x ^ 0 = munit
136+
x ^ y = Inv x ^ (-y)
137+
138+
instance (Multiplicative x) => Divisible (Expr t x o b) where
139+
x / y = curry Mul x $ Inv y
140+
141+
-- | This is meant to be a function that algebraically simplifies the FAPF by
142+
-- 1) using simple identities and ring laws
143+
-- 2) change of numeraire technique.
144+
simplify : (Eq x, Eq b, Eq t, Eq o, Multiplicative x) => Expr t x o b -> Expr t x o b
145+
simplify =
146+
cata unitIdentity
147+
-- . cata zeroIdentity
148+
. cata factNeg
149+
-- . \case [] -> Const aunit
150+
-- [x] -> x
151+
-- xs -> Sum xs
152+
-- . cata distSum
153+
-- . ana commuteLeft
154+
-- . cata mulBeforeSum
155+
156+
-- {- Functions below here are helpers for simplifying the expression tree, used mainly in `simplify` -}
157+
158+
-- | Algebra that simplifies sums, multiplications, expectations involving 0.0.
159+
-- BUG I need to add an additive typeclass constraint, otherwise aunit is just a pattern match.
160+
zeroIdentity : ExprF t x o b (Expr t x o b) -> Expr t x o b
161+
zeroIdentity (MulF (Const aunit) x) = Const aunit
162+
zeroIdentity (MulF x (Const aunit)) = Const aunit
163+
zeroIdentity (SumF xs) = Sum $ filter (not . isZero) xs
164+
where isZero (Const aunit) = True
165+
isZero _ = False
166+
zeroIdentity (E_F (Const aunit) _ _) = Const aunit
167+
zeroIdentity other = embed other
168+
169+
-- | Algebra that simplifies multiplications and divisions by 1.0.
170+
unitIdentity : (Eq x, Eq b, Eq t, Eq o, Multiplicative x) => ExprF t x o b (Expr t x o b) -> Expr t x o b
171+
unitIdentity (MulF a b) | a == munit = b
172+
unitIdentity (MulF a b) | b == munit = a
173+
unitIdentity (InvF x) | x == munit = munit
174+
unitIdentity other = embed other
175+
176+
-- | Algebra that collects and simplifies minuses.
177+
factNeg : ExprF t x o b (Expr t x o b) -> Expr t x o b
178+
factNeg (NegF (Neg x)) = x
179+
-- factNeg (MulF (Neg x) (Neg y)) = Mul (x, y) -- [ML] I think this is redundant
180+
factNeg (MulF (Neg x) y) = Neg $ Mul (x, y)
181+
factNeg (MulF y (Neg x)) = Neg $ Mul (y, x)
182+
factNeg (E_F (Neg x) t f) = Neg $ E x t f
183+
factNeg other = embed other
184+
185+
-- -- | Turn any expression into a list of terms to be summed together
186+
-- distSum : ExprF t x o b [Expr t x o b] -> [Expr t x o b]
187+
-- distSum = \case
188+
-- ConstF x -> [Const x]
189+
-- SumF xs -> join xs
190+
-- MulF xs xs' -> curry Mul <$> xs <*> xs'
191+
-- NegF xs -> Neg <$> xs
192+
-- E_F xs t -> flip E t <$> xs
193+
-- I_F xs xs' -> [I (unroll xs, unroll xs')]
194+
-- ProcF{..} -> [Proc{..}]
195+
-- where unroll xs = Sum xs
196+
197+
-- | Algebra that changes `(a + b) x c` to `c x (a + b)`
198+
-- mulBeforeSum : ExprF t x o b (Expr t x o b) -> Expr t x o b
199+
-- mulBeforeSum (MulF y@Sum{} x) = Mul (x, y)
200+
-- mulBeforeSum (MulF (Mul (x, y@Sum{})) x') = Mul (Mul (x,x'), y)
201+
-- mulBeforeSum other = embed other
202+
203+
-- | Algebra that applies commutative property to all multiplications.
204+
-- commute : ExprF t x o b (Expr t x o b) -> Expr t x o b
205+
-- commute (MulF a b) = embed $ MulF b a
206+
-- commute other = embed other
207+
208+
-- | Change e.g. `a x (b x c)` to `(a x b) x c`.
209+
-- We are not using commutative property, but rather associative --> should rename
210+
-- commuteLeft : Expr t x o b -> ExprF t x o b (Expr t x o b)
211+
-- commuteLeft (Mul (a,(Mul (b, c)))) = Mul (a, b) `MulF` c
212+
-- commuteLeft other = project other

src/main/daml/ContingentClaims/Valuation/Stochastic.daml

Lines changed: 0 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ module ContingentClaims.Valuation.Stochastic (
1111
, fapf
1212
, gbm
1313
, riskless
14-
, simplify
15-
, unitIdentity
1614
) where
1715

1816
import ContingentClaims.Core.Internal.Claim (Claim(..), Inequality(..))
@@ -191,72 +189,3 @@ fapf ccy disc exch val today = flip evalState 0 . futuM coalg . Left . (, today)
191189
val' obs t = ProcF (show obs) (val obs) t
192190
one = munit
193191
zero = aunit
194-
195-
-- | This is meant to be a function that algebraically simplifies the FAPF by
196-
-- 1) using simple identities and ring laws
197-
-- 2) change of numeraire technique.
198-
-- This is still an experimental feature.
199-
simplify : Expr t -> Expr t
200-
simplify =
201-
cata unitIdentity
202-
. cata zeroIdentity
203-
. cata factNeg
204-
. \case [] -> Const aunit
205-
[x] -> x
206-
xs -> Sum xs
207-
. cata distSum
208-
. ana commuteLeft
209-
. cata mulBeforeSum
210-
211-
{- Functions below are helpers for simplifying the expression tree, used mainly in `simplify` -}
212-
213-
zeroIdentity : ExprF t (Expr t) -> Expr t
214-
zeroIdentity (MulF (Const 0.0) x) = Const 0.0
215-
zeroIdentity (MulF x (Const 0.0)) = Const 0.0
216-
zeroIdentity (PowF x (Const 0.0)) = Const 1.0
217-
zeroIdentity (SumF xs) = Sum $ filter (not . isZero) xs
218-
where isZero (Const 0.0) = True
219-
isZero _ = False
220-
zeroIdentity (E_F (Const 0.0) _) = Const 0.0
221-
zeroIdentity other = embed other
222-
223-
-- | HIDE
224-
unitIdentity : ExprF t (Expr t) -> Expr t
225-
unitIdentity (MulF (Const 1.0) x) = x
226-
unitIdentity (MulF x (Const 1.0)) = x
227-
unitIdentity (PowF x (Const 1.0)) = x
228-
unitIdentity other = embed other
229-
230-
factNeg : ExprF t (Expr t) -> Expr t
231-
factNeg (NegF (Neg x)) = x
232-
factNeg (MulF (Neg x) (Neg y)) = Mul (x, y)
233-
factNeg (MulF (Neg x) y) = Neg $ Mul (x, y)
234-
factNeg (MulF y (Neg x)) = Neg $ Mul (y, x)
235-
factNeg (E_F (Neg x) t) = Neg $ E x t
236-
factNeg other = embed other
237-
238-
-- | Turn any expression into a list of terms to be summed together
239-
distSum : ExprF t [Expr t] -> [Expr t]
240-
distSum = \case
241-
ConstF x -> [Const x]
242-
IdentF x -> [Ident x]
243-
SumF xs -> join xs
244-
MulF xs xs' -> curry Mul <$> xs <*> xs'
245-
NegF xs -> Neg <$> xs
246-
E_F xs t -> flip E t <$> xs
247-
I_F xs xs' -> [I (unroll xs, unroll xs')]
248-
PowF xs is -> [Pow (unroll xs, unroll is)]
249-
ProcF{..} -> [Proc{..}]
250-
SupF t τ xs -> [Sup t τ (unroll xs)]
251-
where unroll xs = Sum xs
252-
253-
-- | Change `(a + b) x c` to `c x (a + b)`
254-
mulBeforeSum : ExprF t (Expr t) -> Expr t
255-
mulBeforeSum (MulF y@Sum{} x) = Mul (x, y)
256-
mulBeforeSum (MulF (Mul (x, y@Sum{})) x') = Mul (Mul (x,x'), y)
257-
mulBeforeSum other = embed other
258-
259-
-- | Change e.g. `a x (b x c)` to `(a x b) x c`
260-
commuteLeft : Expr t -> ExprF t (Expr t)
261-
commuteLeft (Mul (x,(Mul (a, b)))) = Mul (x, a) `MulF` b
262-
commuteLeft other = project other

0 commit comments

Comments
 (0)