Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass same parameters to multiple functions?

Tags:

f#

I have a bunch of functions that I want to compute with the same inputs. Is there a better way to see the outputs than the way I chose below?

open MathNet.Numerics.Distributions

// The functions
let EuVanillaPut S0 K T r sigma = 
    let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
    let d2 = d1 - sqrt(T)*sigma
    K*exp(-r*T)*Normal.CDF(0.0,1.0,-d2) - S0*Normal.CDF(0.0,1.0,-d1)

let BSMdelta S0 K T r sigma = 
    let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
    Normal.CDF(0.0,1.0,d1)

let BSMgamma S0 K T r sigma = 
    let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
    Normal.PDF(0.0,1.0,d1) / (S0 * sigma * sqrt(T))

let BSMvega S0 K T r sigma = 
    let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
    Normal.PDF(0.0,1.0,d1) * S0 * sqrt(T)

let BSMthetacall S0 K T r sigma = 
    let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
    let d2 = d1 - sqrt(T)*sigma
    -S0 * Normal.PDF(0.0,1.0,d1) * sigma / (2.0*sqrt(T)) - r*K*exp(-r*T)*Normal.CDF(0.0,1.0,d2)

let BSMthetaput S0 K T r sigma = 
    let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
    let d2 = d1 - sqrt(T)*sigma
    -S0 * Normal.PDF(0.0,1.0,d1) * sigma / (2.0*sqrt(T)) + r*K*exp(-r*T)*Normal.CDF(0.0,1.0,-d2)

// Calling them all at once on the same inputs
// So ugly! Is there a better way?
(30.0, 25.0, 5.0, 0.02, 0.05)
|> fun (S0, K, T, r, sigma) -> [EuVanillaPut S0 K T r sigma; 
                                BSMdelta S0 K T r sigma; 
                                BSMgamma S0 K T r sigma;
                                BSMvega S0 K T r sigma;
                                BSMthetacall S0 K T r sigma;
                                BSMthetaput S0 K T r sigma]

I'm pretty new to F#, should I make a type for this? Should I be using a different data structure as an input for the functions? Any and all pointers are much appreciated.

like image 980
jks612 Avatar asked Apr 26 '16 23:04

jks612


People also ask

How do you pass multiple parameters to a function?

The * symbol is used to pass a variable number of arguments to a function. Typically, this syntax is used to avoid the code failing when we don't know how many arguments will be sent to the function.

Can you pass functions as parameters?

Passing a function as parameter to another functionC++ has two ways to pass a function as a parameter. As you see, you can use either operation() or operation2() to give the same result.

How many parameters can you pass into a function?

There is no maximum limit to pass parameters or arguments to a user defined function. But for a pre-defined function it depends. Not sure, however some sources say that C functions accept at least 127 parameters.

How do you pass a dynamic argument in Python?

Passing keyword arguments with **kwargs As you expect it, Python has also its own way of passing variable-length keyword arguments (or named arguments): this is achieved by using the **kwargs symbol. When using **kwargs, all the keywords arguments you pass to the function are packed inside a dictionary.


1 Answers

As suggested in the comments, one option is to create a list of functions and then use List.map to iterate over all the functions and call them:

let results = 
  [ EuVanillaPut; BSMdelta; BSMgamma ] 
  |> List.map (fun f -> f 30.0 25.0 5.0 0.02 0.05)

I suppose you'd then also want to extract the individual results - to do that, you can use pattern matching (but you will get a warning, because the compiler cannot know that the number of elements in the list is correct):

let [euVanillaPut; bsmdelta; bsmgamma] = results

To avoid the warning, you'd have to write:

match results with
| [euVanillaPut; bsmdelta; bsmgamma] -> // all good
| _ -> failwith "This should not happen..."

Alternatively, you could change the function definition to use tuple (or a record):

let EuVanillaPut (S0, K, T, r, sigma) = 
    let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
    let d2 = d1 - sqrt(T)*sigma
    K*exp(-r*T)*Normal.CDF(0.0,1.0,-d2) - S0*Normal.CDF(0.0,1.0,-d1)

Then you can define a single tuple to hold the parameters and use it as an argument to multiple functions:

let ps = (30.0, 25.0, 5.0, 0.02, 0.05)

let euVanillaPut = EuVanillaPut ps
let bsmdelta = BSMdelta ps
let bsmgamma = BSMgamma ps 

The first approach is a clever trick, but if you are doing this often, then extracting the individual results from the list will be a bit ugly. The second approach is simpler and makes more sense if you have a lot of functions with the same group of parameters.

like image 85
Tomas Petricek Avatar answered Sep 23 '22 22:09

Tomas Petricek