我有一堆我想用相同输入计算的函数.有没有比我下面选择的方式更好的方式来查看输出?
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]
Run Code Online (Sandbox Code Playgroud)
我对F#很新,我应该为此做一个类型吗?我应该使用不同的数据结构作为函数的输入吗?任何和所有指针都非常感谢.
正如评论中所建议的,一个选项是创建一个函数列表,然后使用List.map
迭代所有函数并调用它们:
let results =
[ EuVanillaPut; BSMdelta; BSMgamma ]
|> List.map (fun f -> f 30.0 25.0 5.0 0.02 0.05)
Run Code Online (Sandbox Code Playgroud)
我想你当时也想提取单个结果 - 为此,你可以使用模式匹配(但是你会得到一个警告,因为编译器不能知道列表中元素的数量是否正确):
let [euVanillaPut; bsmdelta; bsmgamma] = results
Run Code Online (Sandbox Code Playgroud)
为了避免警告,你必须写:
match results with
| [euVanillaPut; bsmdelta; bsmgamma] -> // all good
| _ -> failwith "This should not happen..."
Run Code Online (Sandbox Code Playgroud)
或者,您可以将函数定义更改为使用元组(或记录):
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)
Run Code Online (Sandbox Code Playgroud)
然后,您可以定义一个元组来保存参数,并将其用作多个函数的参数:
let ps = (30.0, 25.0, 5.0, 0.02, 0.05)
let euVanillaPut = EuVanillaPut ps
let bsmdelta = BSMdelta ps
let bsmgamma = BSMgamma ps
Run Code Online (Sandbox Code Playgroud)
第一种方法是一个聪明的技巧,但如果你经常这样做,那么从列表中提取单个结果将有点难看.如果你有很多具有相同参数组的函数,第二种方法更简单,更有意义.