Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IndicatorLegacy improvements #732

Merged
merged 1 commit into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Indicator.define.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class DrawIndicator;
_obj.SetHandle(_handle); \
} \
} \
if (Terminal::IsVisualMode()) { \
if (false && Terminal::IsVisualMode()) { \
kenorb marked this conversation as resolved.
Show resolved Hide resolved
/* To avoid error 4806 (ERR_INDICATOR_DATA_NOT_FOUND), */ \
/* we check the number of calculated data only in visual mode. */ \
int _bars_calc = BarsCalculated(_handle); \
Expand All @@ -128,6 +128,7 @@ class DrawIndicator;
} \
} \
if (CopyBuffer(_handle, MODE, SHIFT, 1, _res) < 0) { \
Print(#NATIVE_METHOD_CALL, " = ", _res[0], ", LE = ", _LastError); \
kenorb marked this conversation as resolved.
Show resolved Hide resolved
return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; \
} \
return _res[0];
119 changes: 117 additions & 2 deletions IndicatorLegacy.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,28 @@
#pragma once
#endif

#ifdef INDICATOR_LEGACY_VERSION_MT4
#define INDICATOR_LEGACY_VERSION_DEFINED
#endif

#ifdef INDICATOR_LEGACY_VERSION_MT5
#define INDICATOR_LEGACY_VERSION_DEFINED
#endif

#ifndef INDICATOR_LEGACY_VERSION_DEFINED
#define INDICATOR_LEGACY_VERSION_MT5
#define INDICATOR_LEGACY_VERSION_DEFINED
#endif

#ifdef __MQL4__

#include <EA31337-classes/IndicatorBase.h>
#include <EA31337-classes/Std.h>
#include <EA31337-classes/Storage/ObjectsCache.h>
#include <EA31337-classes/Util.h>

#ifdef INDICATOR_LEGACY_VERSION_MT5

/**
* Replacement for future OnCalculate(). Currently not used, but could be handy in the future.
*/
Expand Down Expand Up @@ -338,8 +353,30 @@ DEFINE_LEGACY_INDICATOR_2(iAD, iAD, string, symbol, int, period);
// int iATR(string symbol, ENUM_TIMEFRAMES period, int ma_period);
DEFINE_LEGACY_INDICATOR_3(iATR, iATR, string, symbol, int, period, int, ma_period);

// int iRSI(string symbol, ENUM_TIMEFRAMES period, int ma_period, int applied_price);
#define T1 string
#define N1 symbol
#define T2 int
#define N2 period
#define T3 int
#define N3 ma_period
#define T4 int
#define N4 applied_price
DEFINE_LEGACY_INDICATOR_4(iRSI, iRSI)
#undef T1
#undef N1
#undef T2
#undef N2
#undef T3
#undef N3
#undef T4
#undef N4
#undef T5
#undef N5
#undef T6
#undef N6

// int iMA(string symbol, ENUM_TIMEFRAMES period, int ma_period, int ma_shift, ENUM_MA_METHOD ma_method,
// ENUM_APPLIED_PRICE applied_price);
#define T1 string
#define N1 symbol
#define T2 int
Expand All @@ -366,4 +403,82 @@ DEFINE_LEGACY_INDICATOR_6(iMA, iMA)
#undef T6
#undef N6

#endif
#endif // INDICATOR_LEGACY_VERSION_MT5
#endif // __MQL4__

#ifdef __MQL5__
#ifdef INDICATOR_LEGACY_VERSION_MT4

/**
* Replacement for future StringConcatenate().
*/
#define StringConcatenate StringConcatenateMT4

/**
* MQL5 wrapper of MQL4's StringConcatenate().
*/
template <typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I,
typename J, typename K, typename L, typename M>
string StringConcatenateMT4(string& _result, A _a, B _b, C _c, D _d, E _e, F _f, G _g, H _h, I _i, J _j, K _k, L _l,
M _m) {
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e + (string)_f + (string)_g + (string)_h +
(string)_i + (string)_j + (string)_k + (string)_l + (string)_m;
}
template <typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I,
typename J, typename K, typename L>
string StringConcatenateMT4(string& _result, A _a, B _b, C _c, D _d, E _e, F _f, G _g, H _h, I _i, J _j, K _k, L _l) {
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e + (string)_f + (string)_g + (string)_h +
(string)_i + (string)_j + (string)_k + (string)_l;
}
template <typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I,
typename J, typename K>
string StringConcatenateMT4(string& _result, A _a, B _b, C _c, D _d, E _e, F _f, G _g, H _h, I _i, J _j, K _k) {
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e + (string)_f + (string)_g + (string)_h +
(string)_i + (string)_j + (string)_k;
}
template <typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I,
typename J>
string StringConcatenateMT4(string& _result, A _a, B _b, C _c, D _d, E _e, F _f, G _g, H _h, I _i, J _j) {
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e + (string)_f + (string)_g + (string)_h +
(string)_i + (string)_j;
}
template <typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I>
string StringConcatenateMT4(string& _result, A _a, B _b, C _c, D _d, E _e, F _f, G _g, H _h, I _i) {
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e + (string)_f + (string)_g + (string)_h +
(string)_i;
}
template <typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H>
string StringConcatenateMT4(string& _result, A _a, B _b, C _c, D _d, E _e, F _f, G _g, H _h) {
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e + (string)_f + (string)_g + (string)_h;
}
template <typename A, typename B, typename C, typename D, typename E, typename F, typename G>
string StringConcatenateMT4(string& _result, A _a, B _b, C _c, D _d, E _e, F _f, G _g) {
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e + (string)_f + (string)_g;
}
template <typename A, typename B, typename C, typename D, typename E, typename F>
string StringConcatenateMT4(string& _result, A _a, B _b, C _c, D _d, E _e, F _f) {
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e + (string)_f;
}
template <typename A, typename B, typename C, typename D, typename E>
string StringConcatenateMT4(string& _result, A _a, B _b, C _c, D _d, E _e) {
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e;
}
template <typename A, typename B, typename C, typename D>
string StringConcatenateMT4(string& _result, A _a, B _b, C _c, D _d) {
return (string)_a + (string)_b + (string)_c + (string)_d;
}
template <typename A, typename B, typename C>
string StringConcatenateMT4(string& _result, A _a, B _b, C _c) {
return (string)_a + (string)_b + (string)_c;
}
template <typename A, typename B>
string StringConcatenateMT4(string& _result, A _a, B _b) {
return (string)_a + (string)_b;
}
template <typename A>
string StringConcatenateMT4(string& _result, A _a) {
return (string)_a;
}

#endif // INDICATOR_LEGACY_VERSION_MT4
#endif // __MQL5__
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
16 changes: 13 additions & 3 deletions Storage/ValueStorage.native.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ template <typename C>
class NativeValueStorage : public ValueStorage<C> {
// Dynamic native array.
C _values[];
int _values_size;

public:
/**
Expand All @@ -49,7 +50,16 @@ class NativeValueStorage : public ValueStorage<C> {
/**
* Initializes array with given one.
*/
void SetData(ARRAY_REF(C, _arr)) { ArrayCopy(_values, _arr); }
void SetData(ARRAY_REF(C, _arr)) {
bool _was_series = ArrayGetAsSeries(_arr);
ArraySetAsSeries(_arr, false);
ArraySetAsSeries(_values, false);
ArrayResize(_values, 0);
ArrayCopy(_values, _arr);
_values_size = ArraySize(_arr);
ArraySetAsSeries(_arr, _was_series);
ArraySetAsSeries(_values, _was_series);
}

/**
* Initializes storage with given value.
Expand All @@ -60,7 +70,7 @@ class NativeValueStorage : public ValueStorage<C> {
* Fetches value from a given shift. Takes into consideration as-series flag.
*/
virtual C Fetch(int _shift) {
if (_shift < 0 || _shift >= ArraySize(_values)) {
if (_shift < 0 || _shift >= _values_size) {
return (C)EMPTY_VALUE;
// Print("Invalid buffer data index: ", _shift, ". Buffer size: ", ArraySize(_values));
// DebugBreak();
Expand All @@ -77,7 +87,7 @@ class NativeValueStorage : public ValueStorage<C> {
/**
* Returns number of values available to fetch (size of the values buffer).
*/
virtual int Size() const { return ArraySize(_values); }
virtual int Size() const { return _values_size; }

/**
* Resizes storage to given size.
Expand Down
Loading