Преобразовать формулу обратного скользящего среднего в 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;
}