在 GNU Octave 中,想在不使用 for 循环的情况下计算向量的 n 天指数移动平均值。
我可以使用 for 循环来做到这一点,但效率低下。我想使用过滤器功能,但是我不确定如何让它正常工作。
在 GNU Octave 中,想在不使用 for 循环的情况下计算向量的 n 天指数移动平均值。
我可以使用 for 循环来做到这一点,但效率低下。我想使用过滤器功能,但是我不确定如何让它正常工作。
将这个线程的位拼凑在一起后
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)
(where n
iswindow
或天数) as alpha
,但我使用1/n
该值是因为该值alpha
符合我的需要。alpha
根据需要进行调整。
或者,我有时需要我的输入和输出向量的尺寸来匹配。NaN
我通过添加meanV = [NaN(window-1,1); meanV];
作为函数的最后一行来填充无效值movingEMean
。simpleAvg
如果你想要一个粗略的估计,你也可以填写它。
在向量的倍频程指数移动平均线上重新发明轮子是愚蠢的。只需在此处复制和粘贴movavg.m
octave 财务包中定义的功能: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