Skip to content

Commit

Permalink
Merge pull request #734 from nseam/dev-tdi-ima-on-array
Browse files Browse the repository at this point in the history
iMAOnArray fixes
  • Loading branch information
kenorb authored Mar 13, 2024
2 parents 8a62da4 + acbac38 commit a7ce6ce
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 8 deletions.
95 changes: 90 additions & 5 deletions Indicators/Indi_MA.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,96 @@ class Indi_MA : public Indicator<IndiMAParams> {
#ifdef __MQL4__
return ::iMAOnArray(price, total, ma_period, ma_shift, ma_method, shift);
#else
// We're reusing the same native array for each consecutive calculation.
NativeValueStorage<double> *_array_storage = Singleton<NativeValueStorage<double>>::Get();
_array_storage.SetData(price);

return iMAOnArray((ValueStorage<double> *)_array_storage, total, ma_period, ma_shift, ma_method, shift, cache);
if (cache != NULL) {
// We're reusing the same native array for each consecutive calculation.
NativeValueStorage<double> *_array_storage = Singleton<NativeValueStorage<double>>::Get();
_array_storage.SetData(price);

return iMAOnArray((ValueStorage<double> *)_array_storage, total, ma_period, ma_shift, ma_method, shift, cache);
} else {
double buf[], arr[], _result, pr, _array;
int pos, i, k, weight;
double sum, lsum;
if (total == 0) total = ArraySize(price);
if (total > 0 && total < ma_period) return (0);
if (shift > total - ma_period - ma_shift) return (0);
bool _was_series = ArrayGetAsSeries(price);
ArraySetAsSeries(price, true);
switch (ma_method) {
case MODE_SMA:
total = ArrayCopy(arr, price, 0, shift + ma_shift, ma_period);
if (ArrayResize(buf, total) < 0) return (0);
sum = 0;
pos = total - 1;
for (i = 1; i < ma_period; i++, pos--) sum += arr[pos];
while (pos >= 0) {
sum += arr[pos];
buf[pos] = sum / ma_period;
sum -= arr[pos + ma_period - 1];
pos--;
}
_result = buf[0];
break;
case MODE_EMA:
if (ArrayResize(buf, total) < 0) return (0);
pr = 2.0 / (ma_period + 1);
pos = total - 2;
while (pos >= 0) {
if (pos == total - 2) buf[pos + 1] = price[pos + 1];
buf[pos] = price[pos] * pr + buf[pos + 1] * (1 - pr);
pos--;
}
_result = buf[0];
break;
case MODE_SMMA:
if (ArrayResize(buf, total) < 0) return (0);
sum = 0;
pos = total - ma_period;
while (pos >= 0) {
if (pos == total - ma_period) {
for (i = 0, k = pos; i < ma_period; i++, k++) {
sum += price[k];
buf[k] = 0;
}
} else
sum = buf[pos + 1] * (ma_period - 1) + price[pos];
buf[pos] = sum / ma_period;
pos--;
}
_result = buf[0];
break;
case MODE_LWMA:
if (ArrayResize(buf, total) < 0) return (0);
sum = 0.0;
lsum = 0.0;
weight = 0;
pos = total - 1;
for (i = 1; i <= ma_period; i++, pos--) {
_array = price[pos];
sum += _array * i;
lsum += _array;
weight += i;
}
pos++;
i = pos + ma_period;
while (pos >= 0) {
buf[pos] = sum / weight;
if (pos == 0) break;
pos--;
i--;
_array = price[pos];
sum = sum - lsum + _array * ma_period;
lsum -= price[i];
lsum += _array;
}
_result = buf[0];
break;
default:
_result = 0;
}
ArraySetAsSeries(price, _was_series);
return _result;
}
#endif
}

Expand Down
4 changes: 2 additions & 2 deletions Indicators/Indi_RSI.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@

#ifndef __MQL4__
// Defines global functions (for MQL4 backward compability).
double iRSI(string _symbol, int _tf, int _period, int _ap, int _shift) {
double iRSI(string _symbol, int _tf, int _period, ENUM_APPLIED_PRICE _ap, int _shift) {
ResetLastError();
return Indi_RSI::iRSI(_symbol, (ENUM_TIMEFRAMES)_tf, _period, (ENUM_APPLIED_PRICE)_ap, _shift);
return Indi_RSI::iRSI(_symbol, (ENUM_TIMEFRAMES)_tf, _period, _ap, _shift);
}
double iRSIOnArray(double &_arr[], int _total, int _period, int _shift) {
ResetLastError();
Expand Down
3 changes: 2 additions & 1 deletion Indicators/Indi_StdDev.mqh
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ class Indi_StdDev : public Indicator<IndiStdDevParams> {
return MathSqrt(std_dev / period);
}

static double iStdDevOnArray(double &array[], int total, int ma_period, int ma_shift, int ma_method, int shift) {
static double iStdDevOnArray(double &array[], int total, int ma_period, int ma_shift, ENUM_MA_METHOD ma_method,
int shift) {
#ifdef __MQL4__
return ::iStdDevOnArray(array, total, ma_period, ma_shift, ma_method, shift);
#endif
Expand Down

0 comments on commit a7ce6ce

Please sign in to comment.