【发布时间】:2023-03-16 09:05:01
【问题描述】:
(这可能是经典,但我想知道如何最好地表达它)
我从左边开始,在某个日期。 对于某些资产,我可以计算从开始日期到某个未来日期的回报。 从那个未来的日期开始,我可以递归地在时间上进一步移动。
我想生成尽可能向右的所有路径,但在某个目标日期之前停止。
这是我的代码。 'a 是一种资产,并且 (DateTime*DateTime) 是我对所述底层证券有报价的 2 倍。
member this.getPaths dtstart dtend : Set<('a*(DateTime*DateTime)) list>=
let rec getPaths dtstart dtend (pastpath:List<'a*(DateTime*DateTime)>) : seq<('a*(DateTime*DateTime)) list>=
let udls = this.getUnderlyingsQuotingAt dtstart
let onestep = seq { for udl in udls do
let qt = this.QuoteNextAfterSrict udl dtstart
if qt.IsNone || (qt.Value |> fst > dtend) then
yield pastpath |> List.rev
else
let nextdate = qt.Value |> fst
yield! (getPaths nextdate dtend ((udl, (dtstart, nextdate))::pastpath) ) }
onestep
getPaths dtstart dtend List.empty |> Set.ofSeq
由于我使用了yield!,最后我会为每次失败收集一条新路径。 所以,最后我必须对我的序列进行重复数据删除。 我的问题是:有没有更好的方法来找到完整的路径,而无需重复数据删除?
我可以进行第二次传递或添加一个 List 参数,但是是否有一些“纯粹”的方法可以一次性做到这一点?
更新
我认为我在许多无用的内部循环中弄错了整个方法。 可能矢量化下一个可用的报价会很有用。我会在重构后更新代码。
更新 2
第一次重写是以下内容,将 yield |> List.rev 上移一级,允许减少不必要的探索。
member this.getPaths dtstart dtend : Set<('a*(DateTime*DateTime)) list>=
let count = ref 0
printfn "computing path from %A to %A " dtstart dtend
let rec getPaths dtstart dtend (pastpath:List<'a*(DateTime*DateTime)>) : seq<('a*(DateTime*DateTime)) list>=
let udls = this.getUnderlyingsQuotingAt dtstart
let udlquotes = udls |> Seq.map (fun udl -> (udl , this.QuoteNextAfterSrict udl dtstart))
|> Seq.filter (fun (_, q) -> q.IsSome)
|> Seq.map (fun (udl, q) -> (udl, q.Value))
|> Seq.filter (fun (_, q) -> fst q <= dtend )
let onestep = seq { if udlquotes.IsEmpty then
yield pastpath |> List.rev
else
for (udl, q) in udlquotes do
let nextdate = (fst q)
count := !count + 1
if !count%1000 = 0 then printfn "!count %A , path : %A " !count pastpath
yield! (getPaths nextdate dtend ((udl, (dtstart, nextdate))::pastpath) )
}
onestep
getPaths dtstart dtend List.empty |> Set.ofSeq
【问题讨论】:
-
我意识到它没有回答您的问题,但您可能会做的一件事是使用类型别名来使您的代码更易于阅读。您至少在两个地方使用了 'a*(DateTimeDateTime)。这可能更容易阅读 type datespan = 'a*(DateTimeDateTime) 然后在您的集合和列表中使用 datespan。正如我所说,我意识到这并不能回答您的问题,但它会使您的代码更易于阅读。
-
你是完全正确的。谢谢你的建议。我将添加一些关于代码的cmets。