【问题标题】:GoogleFinance function to calculate Exponential moving average in google sheets用于计算谷歌表格中的指数移动平均值的 GoogleFinance 函数
【发布时间】:2020-06-07 07:21:40
【问题描述】:

我正在使用 google 表格和 GoogleFinance 函数来获取股票数据。我可以用下面的公式计算一个简单的移动平均线。我试图为每只股票获得长度为 8、13、21、55 的指数移动平均线。关于指数移动平均线公式的任何建议

=AVERAGE(INDEX(GoogleFinance("MSFT","all",WORKDAY(TODAY(),-8),TODAY()),,3))

编辑: 添加我的谷歌表体验

【问题讨论】:

  • 我认为你需要添加更多关于你希望这个函数如何执行的信息,尤其是在数学上,例如你想让它往后看多远。此外,它是否需要适合一个单元格,或者是否可以 (a) 具有用户定义的函数和/或 (b) 在几个单元格/列上具有解决方案。
  • 我也想这样做。你做到了吗?

标签: google-sheets google-sheets-formula moving-average google-finance google-finance-api


【解决方案1】:

我发现this 归功于此用户“Jonathan K 2806”。

试试这个,更简单,可能就足够了:

​​​​/**
 * Calculates the EMA of the range.
 *
 * @param {range} range The range of cells to calculate.
 * @param {number} n The number of trailing samples to give higer weight to, e.g. 30.
 * @return The EMA of the range.
 * @customfunction
 */
function EMA(range, n) {
  if (!range.reduce) {
    return range;
  }

  n = Math.min(n, range.length);
  var a = 2 / (n + 1);

  return range.reduce(function(accumulator, currentValue, index, array) {
    return currentValue != "" ? (currentValue * a + accumulator * (1-a)) : accumulator;
  }, 0);
}

​转到工具 -> 脚本编辑器,将其粘贴到那里并点击保存,然后返回到您的电子表格并在单元格中输入 =EMA($A2:$A100, 10)​ 或者您想使用它。

【讨论】:

  • 我从中获得的价值与我在 tradingview.com 获得的价值无关
  • 很长时间了,我找到了这个答案的参考,大麦可以记住它。对不起。
  • 这有一个非常严重的错误,它将一个起始值 0 添加到累加器中。换句话说,累加器中的第一个值没有得到它的全部权重,只有 alpha。对于极短的范围(n
  • 完全同意@Barett,我刚刚根据作者 Jonathan K 2806 提供了很长时间没有改变的答案。你的努力得到了好评?
  • 如果我需要 200EMA,我应该使用EMA(range, n)range 是最后 200 个每日价格,n 等于 200 吗?像EMA(范围,200)?
【解决方案2】:

以下公式用于计算当前指数移动平均线 (EMA):

EMA = 收盘价 x decay_multiplayer + EMA(前一天)x (1-decay_multiplayer)

EMA 赋予近期价格更高的权重,而常规移动平均线赋予所有值相同的权重。

decay_multiplayer应该选择大于0小于1。

如果您选择较大的数字,如短期移动平均线(更快衰减),如果您选择较小的数字,如长期移动平均线。

要在谷歌表中实现这一点,您必须创建一个代表每天 EMV 值的新列。您必须填写第一个 EMV 值(第一个收盘价),然后使用上面的函数根据当前收盘价和之前的 EMV 值计算每个新的 EMV。

我在这里创建了一个谷歌表作为示例: https://docs.google.com/spreadsheets/d/1ITfRfwQCBV-0amWpZzae2PbKBPAL_8YluUEmU_vbsCI/edit?usp=sharing

【讨论】:

    【解决方案3】:

    上述公式在技术上与指数移动平均线不同。 指数衰减函数如下。 https://en.wikipedia.org/wiki/Exponential_decay

    它通常用于模拟随时间衰减的影响,更重的权重更接近的条目(如上所述)。话虽如此,上面的公式并不相同。

    EWMA/EMA 的实际形式有些不同,可以在这里找到:https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average

    以上内容可能被认为是指数平滑的一种变体,但实际上并非如此:https://en.wikipedia.org/wiki/Exponential_smoothing

    就个人而言,我更喜欢使用 e^-ax 函数来加权平均值。我可以控制前面和后面项目的权重量的“a”参数,以便更好地调整权重。

    currentValueComponent_i=currentValue * e^-time_i/Tau 为您想要的许多项目添加尽可能多的 currentValueComponents。 Tau 是每次迭代中添加的元素衰减 63% 的时间常数,具体取决于加权平均值中包含的项目数。

    来源:我是一名工程师。我经常这样做。

    【讨论】:

      【解决方案4】:

      回馈 Jonathan K 的一些改进。

      • 提高短输入的准确性(range.length = 1 或 2)

      • 边界检查 n

      • 指定输入数组的预期顺序

      • 为 a 给出 1 个替代定义

      • 添加测试功能

        /**
         * Calculates the EMA of the range.
         *
         * @param {range} range The range of cells to calculate. New values (higher weight) should be on the left.
         * @param {number} n The number of trailing samples to give higher weight to, e.g. 30.
         *                   Values below 1 are treated as 1, which will just return the most recent value.
         * @return The EMA of the range.
         * @customfunction
         */
        function EMA(range, n) {
          if (!range.reduce) {
            // can't run ema - bail
            return range;
          } else if (range.flat && range.reverse) {
            // flatten the array if possible & reorganize w/ new values on right (last)
            // NOTE: remove .reverse if the rightmost elements of input range are most recent / need higher weight
            range = range.flat().reverse();
          }
        
          n = Math.max(n,1); // n has lower bound of 1
          var a = 1-(2/(n+1));
          // with the existing a setup, 86% of the total EMA weight will belong to the first n values.
          // an alternate definition for a where n would be the desired number of intervals to keep (?)
          // ex: n = 4 -> quarterly values would get a "mean lifetime" of 1 year.
          // var a = 1-Math.exp(-1 / n);
        
          return range.reduce(function(accumulator, currentValue, index, array) {
            if (currentValue != "") {
              if (accumulator == null) {
                return currentValue;
              } else {
                return currentValue * a + accumulator * (1-a);
              }
            } else {
              return accumulator;
            }
          }, null);
        }
        
        function test() {
          var emaValue = EMA([[13,14],[15,16]], 4);
          Logger.log(emaValue);
        }
        

      【讨论】:

        【解决方案5】:

        最简单的方法是,给定一列X2:X... 和单元格Z1 中的权重系数a,可以递归计算行Y2:Y... 中的指数移动平均值,如下所示:

        EMA
        =X2
        =$Z$1*X3+(1-$Z$1)*(Y2)
        =$Z$1*X4+(1-$Z$1)*(Y3)
        =$Z$1*X5+(1-$Z$1)*(Y4)
        =... # the pattern will repeat itself properly using the drag function 
        

        这里描述了递归公式: https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average

        当然,这只有在数据点之间的间隔始终相同的情况下才有效。

        【讨论】:

          猜你喜欢
          • 2020-01-02
          • 1970-01-01
          • 2021-04-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-04-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多