温馨提示:本文翻译自stackoverflow.com,查看原文请点击:其他 - how can I rewrite, and optimize, this EMA calculation in F#
f#

其他 - 如何在F#中重写和优化此EMA计算

发布于 2020-04-03 23:24:22

这是EMA计算:

let EMA (period : int) (data : double[]) : double[] =
    let multiplier = 2.0 / (double)(period + 1)
    let output = Array.create data.Length System.Double.NaN 

    output.[period - 1] <- data.[0..period - 1] |> Seq.average
    for i in seq {period .. (data.Length - 1)} do
        output.[i] <- (data.[i] * multiplier) + (output.[i - 1] * (1. - multiplier))

    output

您可以使用以下方法进行测试:

EMA 3 [|1.;3.;4.;7.;5.;6.;9.;8.|]

它给出:

[|NaN;Nan;2.66.;4.83;4.91;5.45;7.22;7.61|]

我的第一个问题是关于循环的结尾:

for i in seq {period .. (data.Length - 1)} do
    output.[i] <- (data.[i] * multiplier) + (output.[i - 1] * (1. - multiplier))

可以使用序列运算符重写吗?

我的第二个问题是:是否有快速实现的F#实现?我找不到。

查看更多

提问者
Thomas
被浏览
38
torbonde 2020-01-31 18:08

好吧,我不了解浮动,但是昨天我确实写了一个EMA函数。看起来像这样:

let ema alpha vs =
    (None, vs)
    ||> Array.scan (fun prev x ->
        match prev with
        | None -> Some(x)
        | Some(s) -> Some(alpha*x + (1. - alpha)*s))
    |> Array.choose id

与您的版本一样,我的版本一直追溯到过去,而不仅仅是多个时期。如果您想要这种行为,则可以用替换float option我版本中的type状态float[],甚至可以使用Array.windowed函数来实现它