Created
December 27, 2008 23:10
-
-
Save cbilson/40330 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#light | |
type Currency = { Code : string; Name : string; } | |
type Money = { Amount : float; Currency : Currency } | |
type Asset = | |
| Equity of string * Money | |
| FixedIncome of string * Money | |
| Cash of Money | |
| Future of string * Money | |
| Portfolio of string * Asset list | |
let usd = { Code = "usd"; Name = "US Dollars" } | |
let gbp = { Code = "gbp"; Name = "British Pounds" } | |
let eur = { Code = "eur"; Name = "Euros" } | |
let cad = { Code = "cad"; Name = "Canadian Dollars" } | |
let jpy = { Code = "jpy"; Name = "Japenese Yen" } | |
let chf = { Code = "chf"; Name = "Swiss Francs" } | |
let cny = { Code = "cny"; Name = "Chinese Renminbi" } | |
let sgd = { Code = "sgd"; Name = "Singapore Dollars" } | |
let krw = { Code = "krw"; Name = "Korean Won" } | |
let egp = { Code = "egp"; Name = "Egyptian Pound" } | |
let currencies = [usd; gbp; eur; cad; jpy; chf; cny; sgd; krw; egp]; | |
let portfolio = | |
Portfolio("ABC Corp Reirement Plan", | |
[ | |
Portfolio("US Large Cap Equity Fund", | |
[ | |
Equity("IBM", { Amount = 5000.0; Currency = usd }); | |
Equity("Microsoft", { Amount = 2000.0; Currency = usd }); | |
Equity("Northern Telecom", { Amount = 2000.0; Currency = cad }); | |
]); | |
Portfolio("Global Bond Fund", | |
[ | |
FixedIncome("Lehman Brothers 5y 6.0%", { Amount = 0.05; Currency = usd }); | |
FixedIncome("Fed Farm Credit Bank 15y 5.9%", { Amount = 3400.00; Currency = usd }); | |
FixedIncome("Buoni del Tesoro Poliennali 10y 5.25%", { Amount = 6200.00; Currency = eur }); | |
]); | |
Portfolio("Eurozone Equity Fund", | |
[ | |
Equity("Virgin", { Amount = 5000.0; Currency = gbp }); | |
Equity("France Telecom", { Amount = 2000.0; Currency = eur }); | |
Equity("Total S.A.", { Amount = 6000.0; Currency = eur }); | |
]); | |
Portfolio("Japanese Equity Fund", | |
[ | |
Equity("Asahi", { Amount = 600000.0; Currency = jpy }); | |
Equity("Fujifilm", { Amount = 400000.0; Currency = jpy }); | |
Equity("Chiba Bank", { Amount = 500000.0; Currency = jpy }); | |
]); | |
Portfolio("Emerging Markets Equity Fund", | |
[ | |
Equity("Samsung", { Amount = 8000000.0; Currency = krw }); | |
Equity("Industrial & Commercial Bank of China", { Amount = 50000.0; Currency = cny }); | |
Equity("Upper Egypt Contracting", { Amount = 8000.00; Currency = egp }); | |
]); | |
]) | |
let rawRates = | |
[| | |
(* usd gbp eur cad jpy chf cny sgd krw egp *) | |
(* usd *) 1.0000; 0.6803; 0.7111; 1.2207; 90.650; 1.0700; 6.8409; 1.4494; 1298.9; 5.5250; | |
(* gbp *) 1.4700; 1.0000; 1.0454; 1.7944; 133.26; 1.5729; 10.056; 2.1306; 1909.3; 8.1110; | |
(* eur *) 1.4062; 0.9566; 1.0000; 1.7166; 127.47; 1.5046; 9.6197; 2.0382; 1826.5; 7.7720; | |
(* cad *) 0.8192; 0.5573; 0.5826; 1.0000; 74.261; 0.8765; 5.6041; 1.1874; 1064.0; 4.5210; | |
(* jpy *) 0.0110; 0.0075; 0.0078; 0.0135; 1.0000; 0.0118; 0.0755; 0.0160; 14.329; 0.0610; | |
(* chf *) 0.9346; 0.6358; 0.6646; 1.1408; 84.720; 1.0000; 6.3934; 1.3546; 1213.9; 5.1770; | |
(* cny *) 0.1462; 0.0994; 0.1040; 0.1784; 13.251; 0.1564; 1.0000; 0.2119; 189.87; 0.8080; | |
(* sgd *) 0.6899; 0.4693; 0.4906; 0.8422; 62.543; 0.7382; 4.7198; 1.0000; 896.16; 3.8140; | |
(* krw *) 0.0008; 0.0005; 0.0005; 0.0009; 0.0698; 0.0008; 0.0053; 0.0011; 1.0000; 0.0040; | |
(* egp *) 0.1810; 0.1230; 0.1290; 0.2210; 16.391; 0.1930; 1.2380; 0.2620; 235.09; 1.0000; | |
|] | |
let rateMatrix = | |
let l = List.length currencies | |
Array2.init l l <| fun x y -> Array.get rawRates (x + (y * l)) | |
let mapOfMatrix (ordinals : 'a seq) (matrix : 'b [,]) : Map<('a * 'a), 'b> = | |
ordinals | |
|> Seq.mapi (fun i x -> ordinals |> Seq.mapi (fun j y -> [(y, x), matrix.[i, j]])) | |
|> Seq.concat | |
|> Seq.concat | |
|> Map.of_seq | |
let rateMap = mapOfMatrix currencies rateMatrix | |
let fxConvert b a = {Amount = rateMap.[a.Currency, b] * a.Amount; Currency = b} | |
let rec getCurrencyExposure ccy asset = | |
match asset with | |
| Cash(_) -> { Amount = 0.0; Currency = ccy } | |
| Future(_, _) -> { Amount = 0.0; Currency = ccy } | |
| Equity(_, value) | |
| FixedIncome(_, value) -> if ccy = value.Currency then { Amount = value.Amount; Currency = ccy } | |
else { Amount = 0.0; Currency = ccy } | |
| Portfolio(_, assets) -> let amount = assets | |
|> Seq.sum_by (fun x -> let exposure = getCurrencyExposure ccy x | |
exposure.Amount) | |
{ Amount = amount; Currency = ccy } | |
let exposureByCurrency portfolio = | |
currencies | |
|> List.map (fun ccy -> (ccy, getCurrencyExposure ccy portfolio |> fxConvert usd)) | |
|> List.filter (fun x -> (snd x).Amount <> 0.0) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment