3

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

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

编辑: 添加我的谷歌表体验 在此处输入图像描述

4

5 回答 5

4

我发现这个归功于这个用户“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)​,或者您想使用它。

于 2020-06-11T21:21:48.357 回答
3

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

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

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

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

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

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

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

于 2020-06-17T21:42:05.437 回答
2

上述公式在技术上与指数移动平均线不同。指数衰减函数如下。 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% 的时间常数,具体取决于加权平均值中包含的项目数。

资料来源:我是一名工程师。我定期这样做。

于 2020-07-30T02:48:27.173 回答
2

回馈对 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);
    }
    
于 2021-05-15T23:51:50.807 回答
1

最简单的方法是,给定一列X2:X...和单元格中的权重系数 a,Z1可以递归地计算行中的指数移动平均值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

当然,这仅适用于数据点之间的间隔始终相同的情况。

于 2021-03-25T16:47:52.727 回答