我有一个股票交易所股票价格的数据集:时间 - 价格。但数据点之间的间隔不相等 - 从1到2分钟。
计算此类案件的移动平均线的最佳做法是什么? 如何在Matlab中制作?
我倾向于认为,这些点的权重应该取决于自上一点以来的最后一个时间间隔。我们是否在Matlab中使用自定义权重点计算移动平均值?
答案 0 :(得分:3)
以下是我在上述评论中提到的“天真”方法的一个例子:
% some data (unequally spaced in time, but monotonically non-decreasing)
t = sort(rand(50,1));
x = cumsum(rand(size(t))-0.5);
% linear interpolatation on equally-spaced intervals
tt = linspace(min(t), max(t), numel(t));
xx = interp1(t, x, tt, 'linear');
% plot two data vectors
plot(t, x, 'b.-', tt, xx, 'r.:')
legend({'original', 'equally-spaced'})
答案 1 :(得分:2)
我的答案与湖泊的答案非常相似。但我会在插值方面考虑你的问题。
首先,移动平均值或函数的时间平均值是一段时间内的积分除以时间长度。
在您的情况下,积分可以看作是一个总和,因为大多数情况下每分钟的函数值都是相同的。但是,您的数据具有不等的时间间隔。这可以看作是函数的缺失点。让我解释一下:对于每分钟x
,您应该有一个价格f(x)
。但有时会说x=5
,f(x)
未定义。
你可以摆脱函数不连续性的一种方法是插值 - 根据一些计算规则为缺失点分配一些值。最简单的算法是“保持先前的值”,这实际上是湖泊的想法。
但在这方面思考的好处在于能够使您的数据更准确。它可能不适用于股票市场情况,但通常应该是真实的,例如温度测量或风速,其保证在一段时间内平稳地变化(而不是保持恒定2分钟并且在1秒内突然变化)。您可以使用不同的插值技术来优化数据。从这个意义上讲,“抛光”是可以的,因为无论如何你必须使用“平均”的概念。良好的插值应该使数据更接近已经证明可以解决实际问题的模型。
CODE - 我将最大间隔设置为5分钟,以显示两种方法之间的巨大差异。这取决于您的观察和经验,以决定哪种(或任何其他)方法最好“预测过去”。
% reproduce your scenario
N = 20;
max_interval = 5;
time = randi(max_interval,N,1);
time(1) = 1; % first minute
price = randi(10,N,1);
figure(1)
plot(cumsum(time), price, 'ko-', 'LineWidth', 2);
hold on
% "keeping-previous-value" interpolation
interp1 = zeros(sum(time),1)-1;
interp1(cumsum(time)) = price;
while ismember(-1, interp1)
interp1(interp1==-1) = interp1(find(interp1==-1)-1);
end
plot(interp1, 'bx--')
% "midpoint" interpolation
interp2 = zeros(sum(time),1)-1;
interp2(cumsum(time)) = price;
for ii = 1:length(interp2)
if interp2(ii) == -1
t1 = interp2(ii-1);
t2 = interp2( find(interp2(ii:end)>-1, 1, 'first') +ii-1);
interp2(ii) = (t1+t2)/2;
end
end
plot(interp2, 'rd--')
% "modified-midpoint" interpolation
interp3 = zeros(sum(time),1)-1;
interp3(cumsum(time)) = price;
for ii = 1:length(interp3)
if interp3(ii) == -1
t1 = interp3(ii-1);
t2 = interp3( find(interp3(ii:end)>-1, 1, 'first') +ii-1);
alpha = 1 / find(interp3(ii:end)>-1, 1, 'first');
interp3(ii) = (1-alpha)*t1 + alpha*t2;
end
end
plot(interp3, 'm^--')
hold off
legend('original data', 'interp 1', 'interp 2', 'interp 3')
fprintf(['"keeping-previous-value" (weighted sum) \n', ...
' result: %2.4f \n'], mean(interp1));
fprintf(['"midpoint" (linear interpolation) \n', ...
' result: %2.4f \n'], mean(interp2));
fprintf(['"modified-midpoint" (linear interpolation) \n', ...
' result: %2.4f \n'], mean(interp3));
注意:未定义的点应由NaN
显示,但-1
似乎更容易使用。
答案 2 :(得分:1)
如果您愿意将数据点的时间值离散化,那么解决方案应该非常简单。无论你选择什么样的窗口,只要它是Lipschitz,就可以使用像求和面积表这样的方法,在每个数据点或时间步长的摊销O(1)时间内计算或近似。
否则,使用固定宽度的矩形运行窗口,该窗口仅“捕捉”到数据点。具体来说,仅当数据点加入/离开窗口时,才更新窗口内所有数据点的值的总和。
但是,如果要对数据点使用自定义权重,则上述方法将不再有效。当然,您可以使用多个框函数来近似空间内核。否则,您可能希望查看一般bilateral filtering算法,因为问题可以表示为具有恒定范围内核的双边过滤。有关最近开发的算法,请参阅文章Adaptive Manifolds for Real-Time High-Dimensional Filtering,该算法在此主题上相对容易实现。作者的网站还提供了MATLAB中的代码。
答案 3 :(得分:1)