【问题标题】:Perform a vectorized exponential moving average in octave以八度音阶执行矢量化指数移动平均
【发布时间】:2012-12-09 00:24:35
【问题描述】:

在 GNU Octave 中,想在不使用 for 循环的情况下计算向量的 n 天指数移动平均值。

我可以使用 for 循环来做到这一点,但效率低下。我想使用过滤器功能,但是我不确定如何让它正常工作。

【问题讨论】:

    标签: octave time-series vectorization moving-average


    【解决方案1】:

    从这个线程中拼凑起来

    http://octave.1599824.n4.nabble.com/vectorized-moving-average-td2132090.html

    我使用 Octave 的过滤函数构建了这个函数。

    function meanV = movingEMean(V, window)
      simpleAvg = mean(V(1:window));
      alpha = 1/window;
      X = V(window:end);
      X(1) = simpleAvg;
      meanV = filter(alpha, [1 alpha-1], X, simpleAvg*(1-alpha));
    end
    

    它以简单移动平均线为基础。 V 是用于计算指数移动平均线的数字列向量。 window 是天数的整数。我用的是 12。

    这是这个函数的数学解释。

    http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average

    请注意,页面使用2/(n+1)(其中nwindow 或天数)作为alpha,但我使用1/n,因为alpha 的值符合我的需要。根据需要调整alpha

    或者,有时我需要输入和输出向量的尺寸相匹配。我通过将meanV = [NaN(window-1,1); meanV]; 添加为movingEMean 函数的最后一行,用NaN 填充无效值。如果您想粗略估计,也可以填写simpleAvg

    【讨论】:

      【解决方案2】:

      在向量的八度指数移动平均线上重新发明轮子是愚蠢的。只需在此处复制并粘贴 octave 财务包中定义的movavg.m 函数:https://octave.sourceforge.io/financial

      function [varargout] = movavg(asset, lead, lag, alpha = 0) 
        if nargin < 3 || nargin > 4 
          print_usage (); 
        endif 
        if lead > lag 
          error ("lead must be <= lag") 
        elseif ischar (alpha) 
          if ! strcmpi (alpha, "e") 
            error ("alpha must be 'e' if it is a char"); 
          endif 
        elseif ! isnumeric (alpha) 
          error ("alpha must be numeric or 'e'") 
        endif 
        ## Compute the weights 
        if ischar (alpha) 
          lead = exp(1:lead); 
          lag  = exp(1:lag); 
        else 
          lead = (1:lead).^alpha; 
          lag  = (1:lag).^alpha; 
        endif 
        ## Adjust the weights to equal 1 
        lead = lead / sum (lead); 
        lag  = lag / sum (lag); 
        short = asset; 
        long  = asset; 
        for i = 1:length (asset) 
          if i < length (lead) 
            ## Compute the run-in period 
            r        = length (lead) - i + 1:length(lead); 
            short(i) = dot (asset(1:i), lead(r))./sum (lead(r)); 
          else 
            short(i) = dot (asset(i - length(lead) + 1:i), lead); 
          endif 
          if i < length (lag) 
            r       = length (lag) - i + 1:length(lag); 
            long(i) = dot (asset(1:i), lag(r))./sum (lag(r)); 
          else 
            long(i) = dot (asset(i - length(lag) + 1:i), lag); 
          endif 
        endfor 
        if nargout > 0 
          varargout{1} = short; 
        else 
          plot((1:length(asset))', [asset(:), long(:), short(:)]); 
        endif 
        if nargout > 1 
          varargout{2} = long; 
        endif 
      endfunction 
      

      然后如此调用:

      foo = [NaN; 1;4;8;10;-3;3;4;0;0;3;4;5;6;7;8;9];     
      lead = 7 
      lag = 7
      alpha = 'e' 
      movavg(foo, lead, lag, 'e')
      

      哪些打印:

             NaN
             NaN
             NaN
             NaN
             NaN
             NaN
             NaN
         3.39851
         1.24966
         0.45742
         2.06175
         3.28350
         4.37315
         5.40325
         6.41432
         7.42128
         8.42441
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-08
        • 2012-06-24
        • 1970-01-01
        • 2020-12-31
        • 1970-01-01
        相关资源
        最近更新 更多