【发布时间】:2012-12-09 00:24:35
【问题描述】:
在 GNU Octave 中,想在不使用 for 循环的情况下计算向量的 n 天指数移动平均值。
我可以使用 for 循环来做到这一点,但效率低下。我想使用过滤器功能,但是我不确定如何让它正常工作。
【问题讨论】:
标签: octave time-series vectorization moving-average
在 GNU Octave 中,想在不使用 for 循环的情况下计算向量的 n 天指数移动平均值。
我可以使用 for 循环来做到这一点,但效率低下。我想使用过滤器功能,但是我不确定如何让它正常工作。
【问题讨论】:
标签: octave time-series vectorization moving-average
从这个线程中拼凑起来
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)(其中n 是window 或天数)作为alpha,但我使用1/n,因为alpha 的值符合我的需要。根据需要调整alpha。
或者,有时我需要输入和输出向量的尺寸相匹配。我通过将meanV = [NaN(window-1,1); meanV]; 添加为movingEMean 函数的最后一行,用NaN 填充无效值。如果您想粗略估计,也可以填写simpleAvg。
【讨论】:
在向量的八度指数移动平均线上重新发明轮子是愚蠢的。只需在此处复制并粘贴 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
【讨论】: