具有不同功能和不同时间范围的移动平均线

时间:2014-03-24 00:07:20

标签: matlab function time-series moving-average

我有8个变量的矩阵时间序列数据,大约2500个点(〜10年的星期一),并希望在“移动平均”的基础上计算平均值,方差,偏度和峰度。

让我们说frames = [100 252 504 756] - 我想在每个(时间)帧上每天计算上面的四个函数 - 所以在100天框架的情况下返回第300天,从第201天 - 第300天(总共100天)开始[mean variance skewness kurtosis] ......依此类推。

我知道这意味着我会获得一个数组输出,并且第一个frame天数将是NaN,但我无法弄清楚完成此操作所需的索引...

2 个答案:

答案 0 :(得分:2)

这是一个有趣的问题,因为我认为平均值的最优解决方案与其他样本统计数据不同。

我在下面提供了一个可以解决的模拟示例。

首先,选择一些任意参数并模拟一些数据:

%#Set some arbitrary parameters
T = 100; N = 5;
WindowLength = 10;

%#Simulate some data
X = randn(T, N);

对于均值,请使用filter获取移动平均线:

MeanMA = filter(ones(1, WindowLength) / WindowLength, 1, X);
MeanMA(1:WindowLength-1, :) = nan;

我原本以为使用conv解决此问题的方法如下:

MeanMA = nan(T, N);
for n = 1:N
    MeanMA(WindowLength:T, n) = conv(X(:, n), ones(WindowLength, 1), 'valid');
end
MeanMA = (1/WindowLength) * MeanMA;

但正如@PhilGoddard在评论中指出的那样,filter方法避免了循环的需要。

另请注意,我已选择使输出矩阵中的日期与X中的日期相对应,因此在以后的工作中,您可以对两者使用相同的下标。因此,WindowLength-1中的第一个MeanMA观察结果为nan

对于方差,我看不到如何使用filterconv或甚至运行总和来提高效率,因此我会在每次迭代时手动执行计算:< / p>

VarianceMA = nan(T, N);
for t = WindowLength:T
    VarianceMA(t, :) = var(X(t-WindowLength+1:t, :));
end

我们可以通过利用已经计算出平均移动平均线这一事实来加快速度。只需用以下内容替换上面的内部循环线:

VarianceMA(t, :) = (1/(WindowLength-1)) * sum((bsxfun(@minus, X(t-WindowLength+1:t, :), MeanMA(t, :))).^2);

然而,我怀疑这会有很大的不同。

如果其他人能够看到使用filterconv来获取移动窗口差异的聪明方法,我会非常有兴趣看到它。

我将偏斜和峰度的情况留给OP,因为它们基本上与方差示例相同,但具有适当的函数。

最后一点:如果你将上面的内容转换为一般函数,你可以传入一个匿名函数作为其中一个参数,那么你就有了一个适用于任意选择转换的移动平均例程。

最后,最后一点:对于一系列窗口长度,只需在每个窗口长度上遍历整个代码块。

答案 1 :(得分:1)

我设法制作了一个解决方案,它只使用MATLAB中的基本功能,并且还可以扩展到包含其他功能(对于财务:例如移动夏普比率或移动的Sortino比率)。下面的代码显示了这一点,并包含了充分的评论。

我正在使用一系列对冲基金数据,其中包括10年的每日回报(被检查为静止 - 未在代码中显示)。不幸的是,我没有在示例中得到相应的日期,因此图中的x轴将为“否”。日子&#39;。

% start by importing the data you need - here it is a selection out of an
% excel spreadsheet
returnsHF =  xlsread('HFRXIndices_Final.xlsx','EquityHedgeMarketNeutral','D1:D2742');

% two years to be used for the moving average. (250 business days in one year)
window = 500;

% create zero-matrices to fill with the MA values at each point in time. 
mean_avg = zeros(length(returnsHF)-window,1);
st_dev = zeros(length(returnsHF)-window,1);
skew = zeros(length(returnsHF)-window,1);
kurt = zeros(length(returnsHF)-window,1);

% Now work through the time-series with each of the functions (one can add
% any other functions required), assinging the values to the zero-matrices
for count = window:length(returnsHF)

% This is the most tricky part of the script, the indexing in this section
% The TwoYearReturn is what is shifted along one period at a time with the
% for-loop. 
TwoYearReturn = returnsHF(count-window+1:count);
mean_avg(count-window+1) = mean(TwoYearReturn);
st_dev(count-window+1) = std(TwoYearReturn);
skew(count-window+1) = skewness(TwoYearReturn);
kurt(count-window +1) = kurtosis(TwoYearReturn);
end

% Plot the MAs
subplot(4,1,1), plot(mean_avg)
title('2yr mean')
subplot(4,1,2), plot(st_dev)
title('2yr stdv')
subplot(4,1,3), plot(skew)
title('2yr skewness')
subplot(4,1,4), plot(kurt)
title('2yr kurtosis')