【问题标题】:Moving average for time series with not-equal intervls不等间隔时间序列的移动平均值
【发布时间】:2014-07-31 05:35:32
【问题描述】:

我有一个证券交易所代码价格的数据集:时间 - 价格。但数据点之间的间隔不相等 - 从 1 到 2 分钟。

在这种情况下计算移动平均线的最佳做法是什么? 在matlab中如何制作?

我倾向于认为,点的权重应该取决于自上一点以来的最后时间间隔。我们在 Matlab 中是否具有使用自定义权重计算移动平均值的功能?

【问题讨论】:

  • 要求我们推荐或查找书籍、工具、软件库、教程或其他场外资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,请描述问题以及迄今为止为解决该问题所做的工作。
  • 一种天真的方法是在等间距的间隔内插值数据,然后应用常规移动平均函数。请参阅interp1 函数进行插值。

标签: matlab time-series financial moving-average


【解决方案1】:

这是我在上面的 cmets 中提到的“幼稚”方法的一个示例:

% 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'})

【讨论】:

  • fyi,smooth 函数可以处理非均匀间隔的数据(在其他平滑算法中实现移动平均)
【解决方案2】:

我的答案与lakesh 的答案非常相似。但我会认为你的问题是插值。

首先,移动平均线,或函数的时间平均线,是它在一段时间内的积分,除以时间长度。

在您的情况下,积分可以看作是一个总和,因为大多数情况下,每分钟的函数值都是相同的。但是,您的数据具有不相等的时间间隔。这可以看作是函数的缺失点。让我解释一下:对于每一分钟x,你应该有一个价格f(x)。但有时会说x=5f(x)未定义

消除函数不连续性的方法之一是插值 - 根据一些计算规则为缺失点分配一些值。最简单的算法就是“保持之前的值”,本质上就是lakesh的思路。

但是在这方面思考的好处在于能够使您的数据更加准确。它可能不适用于股票市场的情况,但通常应该是正确的,例如温度测量或风速,保证随着时间的推移平滑变化(而不是保持 2 分钟不变,1 秒钟突然变化)。您可以使用不同的插值技术来完善数据。从这个意义上说,“抛光”是可以的,因为无论如何你都必须使用“平均”的概念。良好的插值应该使数据更接近已被证明可以解决实际问题的模型。

代码 - 我将最大间隔设置为 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 似乎更容易玩。

【讨论】:

    【解决方案3】:

    这是我的建议。

    由于您有不等间隔的数据,请将其转换为等间隔的数据,在不等间隔之间保持价格不变。

    然后你可以使用tsmovavg计算价格序列的移动平均线。

    【讨论】:

      【解决方案4】:

      如果您愿意离散化数据点的时间值,则解决方案应该非常简单。无论您选择哪种类型的窗口,只要是 Lipschitz,都可以使用面积求和表等方法,在每个数据点或时间步的摊销 O(1) 时间内计算或近似。

      否则,使用仅“捕捉”到数据点的固定宽度的矩形运行窗口。具体来说,只有当数据点加入/离开窗口时,才更新窗口内所有数据点的值的总和。

      但是,如果您想对数据点使用自定义权重,则上述方法不再适用。当然,您可以使用多个框函数来近似您的空间内核。否则,您可能想研究一般的bilateral filtering 算法,因为问题可以表述为具有恒定范围内核的双边过滤。请参阅论文Adaptive Manifolds for Real-Time High-Dimensional Filtering,了解最近开发的算法,该算法在该主题上相对容易实现。作者的网站也提供了MATLAB中的代码。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-02-17
        • 1970-01-01
        • 1970-01-01
        • 2020-05-29
        • 1970-01-01
        • 2011-03-08
        • 2013-03-24
        相关资源
        最近更新 更多