我不是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
答案 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.
一些意见:
尝试按顺序定义和发布函数,因为F#编译器从左到右,从上到下。因此,activeReturn
必须先于excessreturn
,top
和bottom
功能必须先于sharperatio
。
excessReturns2
函数出错,最后你有Seq.zip
。我认为这实际上是Seq.sum
或Seq.average
(您希望该期间的总有效回报或平均每日/每月有效回报)。要么你想要一个号码。
这一行(以及下一行):excessReturns2 pfRets bmkRets
:这里的excessReturns2是一个函数,它接受投资组合和基准返回两个参数。此函数将返回一个顶部的数字,因此您可以说let top = excessReturns2 pfRets bmkRets
,同上底部。
最好使用Mathdotnet并从那里调用StandardDeviation函数。无需定义自己的。
如果您有任何问题,请与我们联系。
在Mathdotnet上
这是一个很棒的图书馆,如果你可以依赖它,你应该只能说:
open MathNet.Numerics
open MathNet.Numerics.Statistics
Statistics.StandardDeviation ret1
在划分有效回报时,您还会使用投资组合回报标准差。如果需要查看信息比率,理想情况下应使用主动回报的标准偏差。
答案 1 :(得分:2)
写作时
let top pfRets bmkRets = excessReturns2 pfRets bmkRets
您不根据传入的变量top
和pfRets2
计算bmkRets
的值。相反,您只是定义函数,top
,发生以使用与shapeRatio2
相同的名称作为参数 - 但这些参数是没有说明。
也就是说,这两个函数都接受名为pfRets
和bmkRets
的参数,但调用excessReturns2
而不是也会自动调用top
参数;它只记录它的定义。
显然,同样适用于bottom
。
由于您希望top
和bottom
为值,因此您需要定义而不使用参数(这是最简单的)值和函数之间的区别:后者采用参数,前者不参与:
let sharpeRatio2 pfRets bmkRets x =
let top = excessReturns2 pfRets bmkRets
let bottom = volatilty pfRets false x
let result = top / bottom
result