【问题标题】:A moving average with different functions and varying time-frames具有不同功能和不同时间范围的移动平均线
【发布时间】:2014-05-01 04:33:28
【问题描述】:

我有一个包含 8 个变量的矩阵时间序列数据,大约 2500 个点(约 10 年的周一至周五),我想在“移动平均”的基础上计算均值、方差、偏度和峰度。

假设frames = [100 252 504 756] - 我想每天在每个(时间)框架上计算上面的四个函数 - 所以在 100 天框架的情况下,第 300 天的回报将是[mean variance skewness kurtosis] 从第 201 天到第 300 天(共 100 天)...等等。

我知道这意味着我会得到一个数组输出,而第一个 frame 天数将是 NaN,但我无法确定完成此操作所需的索引...

【问题讨论】:

    标签: matlab function time-series moving-average


    【解决方案1】:

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

    我在下面提供了一个模拟示例,您可以进行操作。

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

    %#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 在 cmets 中指出的那样,filter 方法避免了循环的需要。

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

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

    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,因为它们本质上与方差示例相同,但具有适当的功能。

    最后一点:如果您要将上述转换为通用函数,则可以传入一个匿名函数作为参数之一,然后您将拥有一个移动平均例程,可用于任意选择转换。

    最后,最后一点:对于一系列窗口长度,只需为每个窗口长度循环整个代码块。

    【讨论】:

    • 平均而言,您最好使用filter 函数,它的好处是无需循环。对于其他统计信息,别无选择,只能循环。
    • @PhilGoddard 谢谢。 filter 函数不知何故一直在我的雷达下飞行,直到现在。我已经更新了我的答案以包含这种方法。
    • 感谢您的建议 - 这很有帮助。但是我不认为它必须如此复杂 - 请参阅下面的解决方案。也许您的解决方案以后可以做额外的事情?我的解决方案至少解决了我最初的问题,并且可以扩展以包含更多功能。
    • @DexterMorgan 您确实意识到您的均值/方差/偏度/峰度解决方案与我的方差解决方案相同,对吧?因此,当您说“复杂”时,我假设您指的是我的平均解决方案 - 特别是我对 filter 函数的使用。 Matlab 的一般规则(尽管如今考虑到 JIT 编译器的进步已不太重要)是通过向量化代码来尽可能避免循环。这就是我回答中 filter 函数的目的。
    • 是的,过滤函数确实更适合均值 - 但我想对几个不同的函数执行此操作,而不仅仅是均值。刚刚发布了我的答案,因为它对我有用,我认为它也可能对其他人有所帮助。
    【解决方案2】:

    我设法生成了一个解决方案,它仅使用 MATLAB 中的基本函数,也可以扩展为包含其他函数(对于金融:例如移动夏普比率或移动索提诺比率)。下面的代码显示了这一点,并希望包含足够的注释。

    我正在使用对冲基金数据的时间序列,大约为价值 10 年的每日回报(被检查为固定 - 未显示在代码中)。不幸的是,我在示例中没有相应的日期,因此图中的 x 轴将为“否”。天”。

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

    【讨论】:

      猜你喜欢
      • 2021-11-22
      • 2019-01-01
      • 2010-11-04
      • 1970-01-01
      • 2021-07-10
      • 1970-01-01
      • 1970-01-01
      • 2021-04-19
      • 1970-01-01
      相关资源
      最近更新 更多