F#: Discriminated Unions
I’ve managed to move on somewhat with my F# Market Risk Proof Of Concept (POC). I’ve attached some of the code below. The issue I ran into last night and this morning during train travel was with discriminated unions – which I use for the legs of the trade. As is normal these days, a quick google provided me with the solution I’d been missing. The pattern matching on object type is quite nice.
I’m hoping to be able to use the Parallel LINQ support via F# PowerPack to calculate the cashflows, and pay move from lists to seq.
You’ll notice I am now using [] in the code, since I have multiple files which means you need to be aware of the project file order. Once I get the cashflows generating I’ll look at fsunit
type TradeHeader =
{
TradeDate : DateTime;
}
type Period =
{
PeriodMultiplier : int;
Period : string;
}
type CalculationPeriodDates =
{
EffectiveDate : DateTime;
TerminationDate : DateTime;
CalculationPeriodFrequency : Period;
}
type PaymentDates =
{
PaymentFrequency : Period;
}
type NonNegativeAmountSchedule =
{
InitialValue : double;
Currency : string;
}
type Notional =
{
NotionalStepSchedule : NonNegativeAmountSchedule;
}
type FloatingRateCalculation =
{
FloatingRateIndex : string;
IndexTenor : Period;
}
type FixedRateSchedule =
{
InitialValue : double;
}
type RateCalculation = | Floating of FloatingRateCalculation | Fixed of FixedRateSchedule
type Calculation =
{
NotionalSchedule : Notional;
RateCalculation : RateCalculation;
DayCountFraction : string;
}
type CalculationPeriodAmount =
{
Calculation : Calculation;
}
type InterestRateStream =
{
CalculationPeriodDates : CalculationPeriodDates;
PaymentDates : PaymentDates;
CalculationPeriodAmount : CalculationPeriodAmount;
}
type Trade =
{
Id : int;
Header : TradeHeader;
SwapStream: List<InterestRateStream>;
}
let createTrade (id : int) =
let effectiveDate = new DateTime(2010,1,1)
let termDate = new DateTime(2015,1,1)
let calcPeriod = {PeriodMultiplier = 6; Period = "M";}
let payments = { PeriodMultiplier =6; Period= "M"}
let calPeriodDates = {EffectiveDate=effectiveDate; TerminationDate=termDate; CalculationPeriodFrequency=calcPeriod;}
let initVal = {InitialValue=100000000.00;}
let calPeriodAmt = {Calculation={NotionalSchedule={NotionalStepSchedule={InitialValue=100000000.00;Currency="GBP";};};
RateCalculation=Fixed(initVal);DayCountFraction="30E/360";}}
let pay = {CalculationPeriodDates=calPeriodDates;PaymentDates={PaymentFrequency=payments;};CalculationPeriodAmount=calPeriodAmt;}
let floater = {FloatingRateIndex="USD-LIBOR";IndexTenor=calcPeriod;}
let calPeriodAmt = {Calculation={NotionalSchedule={NotionalStepSchedule={InitialValue=100000000.00;Currency="GBP";};};
RateCalculation=Floating(floater);DayCountFraction="ACT/360";}}
let receive = {CalculationPeriodDates=calPeriodDates;PaymentDates={PaymentFrequency=payments;};CalculationPeriodAmount=calPeriodAmt;}
let trade = {Id=id; Header={TradeDate=DateTime.Now;};SwapStream=[pay;receive;]}
trade
let generateFixedCashflows(fixedLeg:FixedRateSchedule, trade:Trade, valueDate:DateTime) =
// Calculate Dates
0.0
let generateCashflow(stream:InterestRateStream, trade:Trade, valueDate:DateTime) =
match (stream.CalculationPeriodAmount.Calculation.RateCalculation) with
| Fixed(f) ->
printfn "Fixed Leg of %A" trade.Id
generateFixedCashflows(f, trade, valueDate)
| Floating(fl) ->
printfn "Float Leg of %A" trade.Id
0.5
let main =
let valueDate = new DateTime(2010,1,1)
let trade = createTrade 101
let cashFlows =
trade.SwapStream |> List.sumBy (fun x -> generateCashflow(x,trade, valueDate))
let pay = Seq.head trade.SwapStream
Console.ReadLine()
0
[<EntryPoint>]
main



