我有8个变量的矩阵时间序列数据,大约2500个点(〜10年的星期一),并希望在“移动平均”的基础上计算平均值,方差,偏度和峰度。
让我们说frames = [100 252 504 756]
- 我想在每个(时间)帧上每天计算上面的四个函数 - 所以在100天框架的情况下返回第300天,从第201天 - 第300天(总共100天)开始[mean variance skewness kurtosis]
......依此类推。
我知道这意味着我会获得一个数组输出,并且第一个frame
天数将是NaN,但我无法弄清楚完成此操作所需的索引...
答案 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
。
对于方差,我看不到如何使用filter
或conv
或甚至运行总和来提高效率,因此我会在每次迭代时手动执行计算:< / 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);
然而,我怀疑这会有很大的不同。
如果其他人能够看到使用filter
或conv
来获取移动窗口差异的聪明方法,我会非常有兴趣看到它。
我将偏斜和峰度的情况留给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')