F# 累积回报

时间:2021-05-16 21:31:48

标签: f#

我正在做一个项目,我发现自己处于以下情况:

我正在创建一个多空投资组合,其中我目前有每日回报。我的下一步是计算累积回报,但我在尝试这样做时遇到了麻烦。

有人可以帮忙吗?

提前致谢。

代码

let long = myFactorPorts.Rows |> Seq.filter(fun row -> row.PortfolioName = "Mine" && row.Index = Some 3)
let short = myFactorPorts.Rows |> Seq.filter(fun row -> row.PortfolioName = "Mine" && row.Index = Some 1)

type Return = { YearMonth : DateTime; Return : float }
let longShort =
    let shortMap = short |> Seq.map(fun row -> row.YearMonth, row) |> Map
    long
    |> Seq.map(fun longObs -> 
        match Map.tryFind longObs.YearMonth shortMap with
        | None -> failwith "probably your date variables are not aligned"
        | Some shortObs -> { YearMonth = longObs.YearMonth; Return = longObs.Ret - shortObs.Ret }) 
    |> Seq.toArray 

longShort |> Array.take 3

let cumulativereturnslongshort = longShort |> ?? 

1 个答案:

答案 0 :(得分:5)

您的问题有点不清楚,因为您向我们展示了一些与如何获取数据相关的代码,但您并没有过多说明您想做什么以及您遇到了什么问题。

但是,如果我理解的话,您有一个 Return 值数组。我将使用一个简单的例子:

type Return = { YearMonth : DateTime; Return : float }

let longShort =
  [| { YearMonth = DateTime(2021,1,1); Return = 1.0 }
     { YearMonth = DateTime(2021,2,1); Return = -3.0 }
     { YearMonth = DateTime(2021,3,1); Return = 5.0 } 
     { YearMonth = DateTime(2021,4,1); Return = -1.0 } |]

您说您想了解累积回报。我想这意味着只是将之前的回报相加,因此基于上述每月回报的累积回报将是 1、-2、3、2。如果是这种情况,您可以使用 Array.scan:

longShort 
|> Array.scan (fun prev item ->
    { item with Return = item.Return + prev.Return}) 
      { YearMonth = DateTime.MinValue; Return = 0.0 }
|> Array.skip 1

scan 函数允许您使用传递的某些状态为数组中的每个项目计算新值。在这里,我使用前一个 Return 值作为状态(并且传递给 scan 的函数只是将当前值添加到前一个返回值中)。一个技巧是你需要一些初始值,所以我用 Return 创建了一个 Return = 0.0 值,然后跳过这个以获得结果。