 7 people like it.

# DSL for Financial Contracts

Simple domain-specific language for modeling of financial contracts.

 ``` 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: ``` ``````open System // ------------------------------------------------------------------ // Implementation of the DSL /// Defines how a contract can be constructed type Contract = | Trade of string * float | Opposite of Contract | After of DateTime * Contract | Until of DateTime * Contract | Combine of Contract * Contract /// Evaluate contract on a specific day let rec run contract (day:DateTime) = seq { match contract with | Trade(what, amount) -> yield what, amount | Opposite(contract) -> for what, amount in run contract day do yield what, amount * -1.0 | After(dt, contract) -> if day >= dt then yield! run contract day | Until(dt, contract) -> if day <= dt then yield! run contract day | Combine(contract1, contract2) -> yield! run contract1 day yield! run contract2 day } // Functions for creating basic contracts let trade (what, amount) = Trade(what, amount) let after dt contract = After(dt, contract) let until dt contract = Until(dt, contract) let opposite contract = Opposite(contract) let (\$) c1 c2 = Combine(c1, c2) // Functions for creating advanced contracts let purchase (what, amount) = trade(what, amount) let sell (what, amount) = trade(what, amount) |> opposite let onDate dt contract = after dt (until dt contract) let repeatedly (start:DateTime) (span:TimeSpan) times contract = [ for n in 0 .. times -> onDate (start + TimeSpan(span.Ticks * int64 n)) contract ] |> Seq.reduce (\$) let purchaseOn date what = onDate date (purchase what) let sellOn date what = onDate date (sell what) let purchaseRepeatedly dt ts n what = repeatedly dt ts n (purchase what) // ------------------------------------------------------------------ // Example - evaluating contracts // Simple contracts representing sale and repeated purchase let msft = sellOn (DateTime(2012, 4, 21)) ("MSFT", 350.0) let appl = purchaseRepeatedly (DateTime(2012, 4, 23)) (TimeSpan.FromDays(7.0)) 10 ("AAPL", 220.0) // Combination of the two above contracts in one let itcontract = sellOn (DateTime(2012, 4, 30)) ("MSFT", 23.0) \$ purchaseRepeatedly (DateTime(2012, 4, 23)) (TimeSpan.FromDays(7.0)) 10 ("AAPL", 220.0) ``````
namespace System
type Contract =
| Trade of string * float
| Opposite of Contract
| After of DateTime * Contract
| Until of DateTime * Contract
| Combine of Contract * Contract

Full name: Script.Contract

Defines how a contract can be constructed
union case Contract.Trade: string * float -> Contract
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = String

Full name: Microsoft.FSharp.Core.string
Multiple items
val float : value:'T -> float (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float

--------------------
type float = Double

Full name: Microsoft.FSharp.Core.float

--------------------
type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>
union case Contract.Opposite: Contract -> Contract
union case Contract.After: DateTime * Contract -> Contract
Multiple items
type DateTime =
struct
new : ticks:int64 -> DateTime + 10 overloads
member Add : value:TimeSpan -> DateTime
member AddDays : value:float -> DateTime
member AddHours : value:float -> DateTime
member AddMilliseconds : value:float -> DateTime
member AddMinutes : value:float -> DateTime
member AddMonths : months:int -> DateTime
member AddSeconds : value:float -> DateTime
member AddTicks : value:int64 -> DateTime
member AddYears : value:int -> DateTime
...
end

Full name: System.DateTime

--------------------
DateTime()
DateTime(ticks: int64) : unit
DateTime(ticks: int64, kind: DateTimeKind) : unit
DateTime(year: int, month: int, day: int) : unit
DateTime(year: int, month: int, day: int, calendar: Globalization.Calendar) : unit
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int) : unit
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, kind: DateTimeKind) : unit
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, calendar: Globalization.Calendar) : unit
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int) : unit
DateTime(year: int, month: int, day: int, hour: int, minute: int, second: int, millisecond: int, kind: DateTimeKind) : unit
union case Contract.Until: DateTime * Contract -> Contract
union case Contract.Combine: Contract * Contract -> Contract
val run : contract:Contract -> day:DateTime -> seq<string * float>

Full name: Script.run

Evaluate contract on a specific day
val contract : Contract
val day : DateTime
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
val what : string
val amount : float
val dt : DateTime
val contract1 : Contract
val contract2 : Contract
val trade : what:string * amount:float -> Contract

val after : dt:DateTime -> contract:Contract -> Contract

Full name: Script.after
val until : dt:DateTime -> contract:Contract -> Contract

Full name: Script.until
val opposite : contract:Contract -> Contract

Full name: Script.opposite
val c1 : Contract
val c2 : Contract
val purchase : what:string * amount:float -> Contract

Full name: Script.purchase
val sell : what:string * amount:float -> Contract

Full name: Script.sell
val onDate : dt:DateTime -> contract:Contract -> Contract

Full name: Script.onDate
val repeatedly : start:DateTime -> span:TimeSpan -> times:int -> contract:Contract -> Contract

Full name: Script.repeatedly
val start : DateTime
val span : TimeSpan
Multiple items
type TimeSpan =
struct
new : ticks:int64 -> TimeSpan + 3 overloads
member Add : ts:TimeSpan -> TimeSpan
member CompareTo : value:obj -> int + 1 overload
member Days : int
member Duration : unit -> TimeSpan
member Equals : value:obj -> bool + 1 overload
member GetHashCode : unit -> int
member Hours : int
member Milliseconds : int
member Minutes : int
...
end

Full name: System.TimeSpan

--------------------
TimeSpan()
TimeSpan(ticks: int64) : unit
TimeSpan(hours: int, minutes: int, seconds: int) : unit
TimeSpan(days: int, hours: int, minutes: int, seconds: int) : unit
TimeSpan(days: int, hours: int, minutes: int, seconds: int, milliseconds: int) : unit
val times : int
val n : int
property TimeSpan.Ticks: int64
Multiple items
val int64 : value:'T -> int64 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int64

--------------------
type int64 = Int64

Full name: Microsoft.FSharp.Core.int64

--------------------
type int64<'Measure> = int64

Full name: Microsoft.FSharp.Core.int64<_>
module Seq

from Microsoft.FSharp.Collections
val reduce : reduction:('T -> 'T -> 'T) -> source:seq<'T> -> 'T

Full name: Microsoft.FSharp.Collections.Seq.reduce
val purchaseOn : date:DateTime -> string * float -> Contract

Full name: Script.purchaseOn
val date : DateTime
val what : string * float
val sellOn : date:DateTime -> string * float -> Contract

Full name: Script.sellOn
val purchaseRepeatedly : dt:DateTime -> ts:TimeSpan -> n:int -> string * float -> Contract

Full name: Script.purchaseRepeatedly
val ts : TimeSpan
val msft : Contract

Full name: Script.msft
val appl : Contract

Full name: Script.appl
TimeSpan.FromDays(value: float) : TimeSpan
val itcontract : Contract

Full name: Script.itcontract