Преобразовать формулу обратного скользящего среднего в C#

Я ломал голову, пытаясь преобразовать эту формулу в C# безуспешно.

РЕМА Формула. введите описание изображения здесь
Я приличный в выполнении прогги, но не в математике.

Где 0 <λ ≤ 1 - коэффициент затухания.
Когда λ < 1, экспоненциально взвешенное скользящее среднее присваивает ценам больший вес.

В отличие от обычной экспоненциальной скользящей средней, которая придает больший вес самым последним ценам, обратная экспоненциальная скользящая средняя присваивает большие веса самым старым ценам и снижает важность самых последних цен.

2 ответа

эффективное REMA() с проверкой ошибок и контекстно-зависимыми возвращаемыми значениями

Эффективное? Да, избегает повторения повторяющихся дорогостоящих операций (или полагается на приемы оптимизации компилятора)

С проверкой ошибок? Да, почти обязательно для процедур Q/A.

Контекст-конкретнее? Да, возвращает { -1. | REMA( k, lambda ) } что позволяет вызывающей стороне обрабатывать угловой случай ввода ошибок.

double[] fTimeSeriesPRICE;     // a forward-stepping storage ( vs. a MT4 reversed-stepping model )

public double REMA( int k, double lambda )
{   
    if (  lambda <= 0.0        // lambda shall not fall on/under  0.0
       || lambda >  1.0        //        shall not grow beyond    1.0
       || k      <= 0          // depth  shall not be negative or 0
       )
       return -1.0;            // context-protecting RET value

    int aCurrentPricePTR  = fTimeSeriesPRICE.Length - 1;
    int aMaxIterableDEPTH = Math.Min( aCurrentPricePTR, k );

    double numerator   = 0.0;
    double denominator = 0.0;  // REMA formula-expansion contains +1 at the end, never less, never negative
    double lambdator   = 1.0;  // lambda ^ ( ( k - j ) == 0 ) == 1.0

    for ( int aReverseSteppingPTR  = 0;
              aReverseSteppingPTR <= aMaxIterableDEPTH;
              aReverseSteppingPTR++
              )
    {   numerator   += lambdator * fTimeSeriesPRICE[aCurrentPricePTR - aReverseSteppingPTR];
        denominator += lambdator;
        lambdator   *= lambda;
    }
    return numerator / denominator; // numerically fair, denominator never < +1.0
}

Мне кажется, что это одна сумма, разделенная на другую. Вот моя попытка прямого ответа. Мои результаты были определенно средними, которые были более взвешенными по отношению к более ранним записям в списке, но я не претендую на то, чтобы знать, были ли они правильными.

double[] m_prices;

public double Rema(int k, double lambda)
{
    // Simple parameter validation
    if(lambda == 0.0 || k == 0)
        return 0.0;

    // Ensure the iteration will not be larger than the number of entries
    int t = m_prices.Length - 1;
    k = Math.Min(t, k);

    double numerator = 0;
    double denominator = 0;
    for (int j = 0; j <= k; j++)
    {
        // Preform the 2 sigma operations from the formula
        numerator += Math.Pow(lambda, k-j) * m_prices[t - j];
        denominator += Math.Pow(lambda, k-j);
    }

    // Simple error check
    if (denominator == 0.0)
        return 0.0;
    return numerator / denominator;
}
Другие вопросы по тегам