f# at pfa pension - meetupfiles.meetup.com/10193032/fsharp_at_pfa_pension.pdf · f# at pfa pension...

Post on 17-Jul-2020

6 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

F# AT PFA PENSIONKRISTIAN SCHMIDT - ACTUARIAL MODELLING

MAIL: KRISTIAN@KREUTZ.US

WEB: WWW.KREUTZ.US

TWITTER: @KREUTZSCHMIDT

WHAT DO WE DO?Insurance mathematicsLife insurance in PFA's caseLiability calculations, making sure we will be able to fulfillour obligationsPricing. What do our customers need to pay for insurance?

WHAT DO WE DO? MY DEPARTMENTSize: One manager and three analystsInsurance contract valuationMortality rate modellingLiability calculations for all policiesAd hoc analysis of potential model changes

THE EVOLUTION OF OUR F# USERewrite of our pricing engine from C++ to C#Heard some buzz about functional programmingStarted intro to scala course

THEN I TRIED TO GET SBT WORKING

FAST FORWARD A FEW MONTHSSomehow heard about F#Start fiddling at home, read a lot offsharpforfunandprofit.comProposed rewriting some of the existing classesFirst F# commit 23/05/2014

A YEAR AND A HALF LATERThe department's projects are a mix of C#, F# and SASF# is the default language for new projectsA rewrite of our SAS code in F# is under wayThe manager and one other analyst completedProgramming in F# on edX.org

LANGUAGE UPS AND DOWNSTHE GOOD PARTS

IMMUTABILITYSensible defaultAlso very nice to have mutability in a pinch!

TYPESDiscriminated unions: Where have you been all my life?!The killer app - ease of declarationStructural equality by default

PATTERN MATCHINGSAS

1: 2: 3: 4: 5: 6: 7: 8: 9: 10:

* Pi faktorer, pi(i, j). Vi skelner imellem STDLIV 2,0% (j=3), STDLIV 3,pi(01, 3) = 11.040000/12; pi(03, 3) = 03.686074/4; pi(06, 3) = 01.847599/2; pi(12, 3) = 00.928373/1; pi(01, 2) = 11.040000/12; pi(03, 2) = 03.690555/4; pi(06, 2) = 01.853212/2; pi(12, 2) = 00.934575/1; ...

F# - STARTING WITH THE TYPES

1: 2: 3: 4: 5: 6: 7: 8: 9:

type Period = | ``One Month`` | ``Three Months`` | ``Six Months`` | ``Twelve Months``

type Basis = | ``STDLIV 3,5%`` | ``STDLIV 2%`` | ``Five %`` | Other

F# - THEN THE LOOKUP FUNCTION

1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:

let PiFaktor period basis = match period, basis with | ``One Month``, ``STDLIV 2%`` ­> 11.040000m / 12m | ``Three Months``, ``STDLIV 2%`` ­> 3.686074m / 4m | ``Six Months``, ``STDLIV 2%`` ­> 1.847599m / 2m | ``Twelve Months``, ``STDLIV 2%`` ­> 0.928373m | ``One Month``, ``STDLIV 3,5%`` ­> 11.040000m / 12m | ``Three Months``, ``STDLIV 3,5%`` ­> 3.690555m / 4m | ``Six Months``, ``STDLIV 3,5%`` ­> 1.853212m / 2m | ``Twelve Months``, ``STDLIV 3,5%`` ­> 0.934575m ...

EASY TO USE STANDARD LIBRARYThe core sequence modules (Array, List, Seq) have a ton ofuseful functionsFold, reduce, scan, partition, groupByNone of these are hard to implement, but easy to screw up

EASY TO USE STANDARD LIBRARYEXAMPLE - GROUPBY F#

1: let groups = list |> List.groupBy f

EASY TO USE STANDARD LIBRARYEXAMPLE - GROUPBY C#

LANGUAGE UPS AND DOWNSTHE NOT-SO-GOOD PARTS

VISUAL STUDIO SUPPORTIntellisense pales in comparison to C#VS Power Tools help, but it's not R#erC#/F# project interop, find references/gotoDoesn't feel like a first class citizen

DEBUGGING PIPES1: 2: 3: 4:

let result = initialValue |> operation1 |> operation2 |> operation3

DEBUGGING PIPES1: 2: 3:

let result1 = operation1 initialValue let result2 = operation2 result1 let result = operation3 result2

VARYING QUALITY OF OPEN SOURCE LIBRARIESLacking docs/tutorialsStill in their infancy, feature wise

MODEL INTROCONTRACT VALUATION

AN EXAMPLEI am a healthy 29 year old maleIf I die before age 67, my wife gets 1.000.000 DKKWhat is the probability weighed value of this contract?

A MODEL FRAMEWORK

Key conceptsState: Active, Disabled & DeadIntensity: "Probability" of jumping from one state toanotherPayment: Money received jumping to (or staying in) a givenstate

SOLUTIONMath: Set of ordinary differential equationsNumerical procedures: Runge-Kutta methodsCode: Model setup in F#, numerical procedure in C#, bulkcalculator in F#

SCALEProcess about 25 million contracts at the start of everymonthTakes about 15 hours on a 64 core server~150 ms average compute time

COMMERCIAL SOLUTIONS

Edlund's ActulusSchantz Valuation

DECLARATIVE COMPUTATION EXPRESSIONSAND THE PROBLEM IT HELPED US SOLVE

REGULAR COMPUTATION EXPRESSIONSDefines a series of computations in a specific contextSee for example: async, seq

DECLARATIVE COMPUTATION EXPRESSIONSDefines custom operators that augment a record type

Example from F# DSL Cheatsheet

1: 2: 3: 4: 5: 6:

let example = trade buy 100 "IBM" Shares At Max 45 sell 40 "Sun" Shares At Min 24 buy 25 "CISCO" Shares At Max 56

DECLARATIVE COMPUTATION EXPRESSIONS - WHY?No need to write your own parserGet type checking for freeTradeoff between compile time type checking and syntaxflexibility

A MODEL FRAMEWORK

State: Active, Disabled & DeadIntensity: "Probability" of jumping from one state toanotherThe problem: Keeping track of the intensities

THE OLD SOLUTION

THE NEW SOLUTION - STATES1: 2: 3: 4:

type State = | Active | Dead | Disabled

THE NEW SOLUTION - INTENSITIES1: 2: 3: 4: 5:

type InputJumpIntensity = | GM of a : float * b : float * c : float | Interpolated of float list | Constant of value : float | ...

G (age) = a +M(a,b,c) 10b+c∗age−10

Implements common operators (+, -, *)Enables us to express computations previously done inexcel directly in the code

THE NEW SOLUTION 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:

let (=>) a b = (a,b)

let ``ValuationBasis Name`` = valuationBasis intensity Male (Active => Dead) ``Intensity 1`` intensity Male (Active => Disabled) ``Intensity 2`` intensity Male (Disabled => Active) ``Intensity 3`` intensity Male (Disabled => Dead) ``Intensity 4``

...

THE NEW SOLUTION1: 2: 3:

[<ContainsValuationBases>] module InputValuationBases = let ``ValuationBasis Name`` = ...

Valuation bases are automatically added where they areneededAutomatic report generation (Word / )LT XA E

SUMMARY

QUESTIONS?THANK YOU FOR YOUR TIME

MAIL: KRISTIAN@KREUTZ.US

WEB: WWW.KREUTZ.US

TWITTER: @KREUTZSCHMIDT

1: 2: 3: 4: 5: 6:

type Builder() = member __.Yield(()) = The default record

[<CustomOperation("customOp")>] member __.CustomOp(record, parameters) = The augmented record

top related