F#分割功能错误:期望支持运营商的类型' /'但给定一个函数类型

时间:2016-09-07 07:13:25

标签: function f#

我不是F#程序员。我正在修改现有的库。

我正在尝试并慢慢地捡起它。

我想要做的就是划分两个功能。

我可以看到它通过库的其余部分完成,所以我知道它可能然而当我尝试划分我得到错误

"期待支持运营商的类型' /'但给定一个函数类型。您可能缺少函数的参数"

这是发生错误的地方

let sharpeRatio2 pfRets bmkRets x  =
    let top pfRets bmkRets = excessReturns2 pfRets bmkRets
    let bottom pfRets x = volatilty pfRets false x
    let result = top / bottom
    result

我认为所谓的子函数都很好,我创建它的波动率唯一的问号应该将std结果乘以sqrt(12)

顶部(退货)

let excessReturns2 (pfRets: seq<float>) bmkRets =
    Seq.zip pfRets bmkRets |> Seq.map activeReturn
    |> Seq.zip

let inline activeReturn (ret, bmkRet) = ret - bmkRet

底部(波动率)

    let var xs nmethod = 
    match Seq.fold (fun (i, s, sumsq) x -> i + 1, s + x, sumsq + x * x) (0, 0., 0.) xs with
    | 0, _, _ -> 0.
    | 1, _, _ when not nmethod -> 0.
    | n, xsum, xsumsq ->
        // denominator is (n-1) or n
        let d = if nmethod then float n else float n - 1.
        (xsumsq - xsum * xsum / float n) / d

    let std xs nmethod = sqrt (var xs nmethod)

    let volatilty xs nmethod x = (std xs nmethod) * sqrt (x)

欢迎任何想法

谢谢gws

2 个答案:

答案 0 :(得分:2)

这应该适合你:

open System
let rnd = Random()
rnd.NextDouble()

let ret1 = List.init 100 (fun _ -> rnd.NextDouble() - 0.5)
let ret2 = List.init 100 (fun _ -> rnd.NextDouble() - 0.5)

let inline activeReturn (ret, bmkRet) = ret - bmkRet
let excessReturns2 (pfRets: seq<float>) bmkRets =
    Seq.zip pfRets bmkRets |> Seq.map activeReturn |> Seq.sum

let var xs nmethod = 
    match Seq.fold (fun (i, s, sumsq) x -> i + 1, s + x, sumsq + x * x) (0, 0., 0.) xs with
    | 0, _, _ -> 0.
    | 1, _, _ when not nmethod -> 0.
    | n, xsum, xsumsq ->
        // denominator is (n-1) or n
        let d = if nmethod then float n else float n - 1.
        (xsumsq - xsum * xsum / float n) / d

let std xs nmethod = sqrt (var xs nmethod)
let volatilty xs nmethod x = (std xs nmethod) * sqrt (x)


let sharpeRatio2 pfRets bmkRets x  =
    let top = excessReturns2 pfRets bmkRets
    let bottom  = volatilty pfRets false x
    let result = top / bottom
    result

sharpeRatio2 ret1 ret2 12.

一些意见:

  1. 尝试按顺序定义和发布函数,因为F#编译器从左到右,从上到下。因此,activeReturn必须先于excessreturntopbottom功能必须先于sharperatio

  2. excessReturns2函数出错,最后你有Seq.zip。我认为这实际上是Seq.sumSeq.average(您希望该期间的总有效回报或平均每日/每月有效回报)。要么你想要一个号码。

  3. 这一行(以及下一行):excessReturns2 pfRets bmkRets:这里的excessReturns2是一个函数,它接受投资组合和基准返回两个参数。此函数将返回一个顶部的数字,因此您可以说let top = excessReturns2 pfRets bmkRets,同上底部。

  4. 最好使用Mathdotnet并从那里调用StandardDeviation函数。无需定义自己的。

  5. 如果您有任何问题,请与我们联系。

    在Mathdotnet上

    这是一个很棒的图书馆,如果你可以依赖它,你应该只能说:

    open MathNet.Numerics
    open MathNet.Numerics.Statistics
    
    Statistics.StandardDeviation ret1
    

    在划分有效回报时,您还会使用投资组合回报标准差。如果需要查看信息比率,理想情况下应使用主动回报的标准偏差。

答案 1 :(得分:2)

写作时

let top pfRets bmkRets = excessReturns2 pfRets bmkRets

根据传入的变量toppfRets2计算bmkRets的值。相反,您只是定义函数top发生以使用与shapeRatio2相同的名称作为参数 - 但这些参数是没有说明。

也就是说,这两个函数都接受名为pfRetsbmkRets的参数,但调用excessReturns2 而不是也会自动调用top参数;它只记录它的定义。

显然,同样适用于bottom

由于您希望topbottom,因此您需要定义而不使用参数(这是最简单的)值和函数之间的区别:后者采用参数,前者不参与:

let sharpeRatio2 pfRets bmkRets x  =
    let top = excessReturns2 pfRets bmkRets
    let bottom = volatilty pfRets false x
    let result = top / bottom
    result