Skip to content

Commit 9fb1008

Browse files
committed
Refs EA31337-classes/EA31337-indicators-other#13, EA31337-classes/EA31337-indicators-other#15. WIP. TDI-RT-Clone and Heiken_Ashi_Smoothed indicators made to work in MT5.
1 parent 0ddfa58 commit 9fb1008

File tree

4 files changed

+222
-11
lines changed

4 files changed

+222
-11
lines changed

Indicator.define.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ class DrawIndicator;
116116
_obj.SetHandle(_handle); \
117117
} \
118118
} \
119-
if (Terminal::IsVisualMode()) { \
119+
if (false && Terminal::IsVisualMode()) { \
120120
/* To avoid error 4806 (ERR_INDICATOR_DATA_NOT_FOUND), */ \
121121
/* we check the number of calculated data only in visual mode. */ \
122122
int _bars_calc = BarsCalculated(_handle); \
@@ -128,6 +128,7 @@ class DrawIndicator;
128128
} \
129129
} \
130130
if (CopyBuffer(_handle, MODE, SHIFT, 1, _res) < 0) { \
131+
Print(#NATIVE_METHOD_CALL, " = ", _res[0], ", LE = ", _LastError); \
131132
return ArraySize(_res) > 0 ? _res[0] : EMPTY_VALUE; \
132133
} \
133134
return _res[0];

IndicatorLegacy.h

Lines changed: 117 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,28 @@
77
#pragma once
88
#endif
99

10+
#ifdef INDICATOR_LEGACY_VERSION_MT4
11+
#define INDICATOR_LEGACY_VERSION_DEFINED
12+
#endif
13+
14+
#ifdef INDICATOR_LEGACY_VERSION_MT5
15+
#define INDICATOR_LEGACY_VERSION_DEFINED
16+
#endif
17+
18+
#ifndef INDICATOR_LEGACY_VERSION_DEFINED
19+
#define INDICATOR_LEGACY_VERSION_MT5
20+
#define INDICATOR_LEGACY_VERSION_DEFINED
21+
#endif
22+
1023
#ifdef __MQL4__
1124

1225
#include <EA31337-classes/IndicatorBase.h>
1326
#include <EA31337-classes/Std.h>
1427
#include <EA31337-classes/Storage/ObjectsCache.h>
1528
#include <EA31337-classes/Util.h>
1629

30+
#ifdef INDICATOR_LEGACY_VERSION_MT5
31+
1732
/**
1833
* Replacement for future OnCalculate(). Currently not used, but could be handy in the future.
1934
*/
@@ -338,8 +353,30 @@ DEFINE_LEGACY_INDICATOR_2(iAD, iAD, string, symbol, int, period);
338353
// int iATR(string symbol, ENUM_TIMEFRAMES period, int ma_period);
339354
DEFINE_LEGACY_INDICATOR_3(iATR, iATR, string, symbol, int, period, int, ma_period);
340355

356+
// int iRSI(string symbol, ENUM_TIMEFRAMES period, int ma_period, int applied_price);
357+
#define T1 string
358+
#define N1 symbol
359+
#define T2 int
360+
#define N2 period
361+
#define T3 int
362+
#define N3 ma_period
363+
#define T4 int
364+
#define N4 applied_price
365+
DEFINE_LEGACY_INDICATOR_4(iRSI, iRSI)
366+
#undef T1
367+
#undef N1
368+
#undef T2
369+
#undef N2
370+
#undef T3
371+
#undef N3
372+
#undef T4
373+
#undef N4
374+
#undef T5
375+
#undef N5
376+
#undef T6
377+
#undef N6
378+
341379
// int iMA(string symbol, ENUM_TIMEFRAMES period, int ma_period, int ma_shift, ENUM_MA_METHOD ma_method,
342-
// ENUM_APPLIED_PRICE applied_price);
343380
#define T1 string
344381
#define N1 symbol
345382
#define T2 int
@@ -366,4 +403,82 @@ DEFINE_LEGACY_INDICATOR_6(iMA, iMA)
366403
#undef T6
367404
#undef N6
368405

369-
#endif
406+
#endif // INDICATOR_LEGACY_VERSION_MT5
407+
#endif // __MQL4__
408+
409+
#ifdef __MQL5__
410+
#ifdef INDICATOR_LEGACY_VERSION_MT4
411+
412+
/**
413+
* Replacement for future StringConcatenate().
414+
*/
415+
#define StringConcatenate StringConcatenateMT4
416+
417+
/**
418+
* MQL5 wrapper of MQL4's StringConcatenate().
419+
*/
420+
template <typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I,
421+
typename J, typename K, typename L, typename M>
422+
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,
423+
M _m) {
424+
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e + (string)_f + (string)_g + (string)_h +
425+
(string)_i + (string)_j + (string)_k + (string)_l + (string)_m;
426+
}
427+
template <typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I,
428+
typename J, typename K, typename L>
429+
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) {
430+
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e + (string)_f + (string)_g + (string)_h +
431+
(string)_i + (string)_j + (string)_k + (string)_l;
432+
}
433+
template <typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I,
434+
typename J, typename K>
435+
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) {
436+
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e + (string)_f + (string)_g + (string)_h +
437+
(string)_i + (string)_j + (string)_k;
438+
}
439+
template <typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I,
440+
typename J>
441+
string StringConcatenateMT4(string& _result, A _a, B _b, C _c, D _d, E _e, F _f, G _g, H _h, I _i, J _j) {
442+
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e + (string)_f + (string)_g + (string)_h +
443+
(string)_i + (string)_j;
444+
}
445+
template <typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I>
446+
string StringConcatenateMT4(string& _result, A _a, B _b, C _c, D _d, E _e, F _f, G _g, H _h, I _i) {
447+
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e + (string)_f + (string)_g + (string)_h +
448+
(string)_i;
449+
}
450+
template <typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H>
451+
string StringConcatenateMT4(string& _result, A _a, B _b, C _c, D _d, E _e, F _f, G _g, H _h) {
452+
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e + (string)_f + (string)_g + (string)_h;
453+
}
454+
template <typename A, typename B, typename C, typename D, typename E, typename F, typename G>
455+
string StringConcatenateMT4(string& _result, A _a, B _b, C _c, D _d, E _e, F _f, G _g) {
456+
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e + (string)_f + (string)_g;
457+
}
458+
template <typename A, typename B, typename C, typename D, typename E, typename F>
459+
string StringConcatenateMT4(string& _result, A _a, B _b, C _c, D _d, E _e, F _f) {
460+
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e + (string)_f;
461+
}
462+
template <typename A, typename B, typename C, typename D, typename E>
463+
string StringConcatenateMT4(string& _result, A _a, B _b, C _c, D _d, E _e) {
464+
return (string)_a + (string)_b + (string)_c + (string)_d + (string)_e;
465+
}
466+
template <typename A, typename B, typename C, typename D>
467+
string StringConcatenateMT4(string& _result, A _a, B _b, C _c, D _d) {
468+
return (string)_a + (string)_b + (string)_c + (string)_d;
469+
}
470+
template <typename A, typename B, typename C>
471+
string StringConcatenateMT4(string& _result, A _a, B _b, C _c) {
472+
return (string)_a + (string)_b + (string)_c;
473+
}
474+
template <typename A, typename B>
475+
string StringConcatenateMT4(string& _result, A _a, B _b) {
476+
return (string)_a + (string)_b;
477+
}
478+
template <typename A>
479+
string StringConcatenateMT4(string& _result, A _a) {
480+
return (string)_a;
481+
}
482+
483+
#endif // INDICATOR_LEGACY_VERSION_MT4
484+
#endif // __MQL5__

Indicators/Indi_MA.mqh

Lines changed: 90 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,96 @@ class Indi_MA : public Indicator<IndiMAParams> {
141141
#ifdef __MQL4__
142142
return ::iMAOnArray(price, total, ma_period, ma_shift, ma_method, shift);
143143
#else
144-
// We're reusing the same native array for each consecutive calculation.
145-
NativeValueStorage<double> *_array_storage = Singleton<NativeValueStorage<double>>::Get();
146-
_array_storage.SetData(price);
147-
148-
return iMAOnArray((ValueStorage<double> *)_array_storage, total, ma_period, ma_shift, ma_method, shift, cache);
144+
if (cache != NULL) {
145+
// We're reusing the same native array for each consecutive calculation.
146+
NativeValueStorage<double> *_array_storage = Singleton<NativeValueStorage<double>>::Get();
147+
_array_storage.SetData(price);
148+
149+
return iMAOnArray((ValueStorage<double> *)_array_storage, total, ma_period, ma_shift, ma_method, shift, cache);
150+
} else {
151+
double buf[], arr[], _result, pr, _array;
152+
int pos, i, k, weight;
153+
double sum, lsum;
154+
if (total == 0) total = ArraySize(price);
155+
if (total > 0 && total < ma_period) return (0);
156+
if (shift > total - ma_period - ma_shift) return (0);
157+
bool _was_series = ArrayGetAsSeries(price);
158+
ArraySetAsSeries(price, true);
159+
switch (ma_method) {
160+
case MODE_SMA:
161+
total = ArrayCopy(arr, price, 0, shift + ma_shift, ma_period);
162+
if (ArrayResize(buf, total) < 0) return (0);
163+
sum = 0;
164+
pos = total - 1;
165+
for (i = 1; i < ma_period; i++, pos--) sum += arr[pos];
166+
while (pos >= 0) {
167+
sum += arr[pos];
168+
buf[pos] = sum / ma_period;
169+
sum -= arr[pos + ma_period - 1];
170+
pos--;
171+
}
172+
_result = buf[0];
173+
break;
174+
case MODE_EMA:
175+
if (ArrayResize(buf, total) < 0) return (0);
176+
pr = 2.0 / (ma_period + 1);
177+
pos = total - 2;
178+
while (pos >= 0) {
179+
if (pos == total - 2) buf[pos + 1] = price[pos + 1];
180+
buf[pos] = price[pos] * pr + buf[pos + 1] * (1 - pr);
181+
pos--;
182+
}
183+
_result = buf[0];
184+
break;
185+
case MODE_SMMA:
186+
if (ArrayResize(buf, total) < 0) return (0);
187+
sum = 0;
188+
pos = total - ma_period;
189+
while (pos >= 0) {
190+
if (pos == total - ma_period) {
191+
for (i = 0, k = pos; i < ma_period; i++, k++) {
192+
sum += price[k];
193+
buf[k] = 0;
194+
}
195+
} else
196+
sum = buf[pos + 1] * (ma_period - 1) + price[pos];
197+
buf[pos] = sum / ma_period;
198+
pos--;
199+
}
200+
_result = buf[0];
201+
break;
202+
case MODE_LWMA:
203+
if (ArrayResize(buf, total) < 0) return (0);
204+
sum = 0.0;
205+
lsum = 0.0;
206+
weight = 0;
207+
pos = total - 1;
208+
for (i = 1; i <= ma_period; i++, pos--) {
209+
_array = price[pos];
210+
sum += _array * i;
211+
lsum += _array;
212+
weight += i;
213+
}
214+
pos++;
215+
i = pos + ma_period;
216+
while (pos >= 0) {
217+
buf[pos] = sum / weight;
218+
if (pos == 0) break;
219+
pos--;
220+
i--;
221+
_array = price[pos];
222+
sum = sum - lsum + _array * ma_period;
223+
lsum -= price[i];
224+
lsum += _array;
225+
}
226+
_result = buf[0];
227+
break;
228+
default:
229+
_result = 0;
230+
}
231+
ArraySetAsSeries(price, _was_series);
232+
return _result;
233+
}
149234
#endif
150235
}
151236

Storage/ValueStorage.native.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ template <typename C>
3434
class NativeValueStorage : public ValueStorage<C> {
3535
// Dynamic native array.
3636
C _values[];
37+
int _values_size;
3738

3839
public:
3940
/**
@@ -49,7 +50,16 @@ class NativeValueStorage : public ValueStorage<C> {
4950
/**
5051
* Initializes array with given one.
5152
*/
52-
void SetData(ARRAY_REF(C, _arr)) { ArrayCopy(_values, _arr); }
53+
void SetData(ARRAY_REF(C, _arr)) {
54+
bool _was_series = ArrayGetAsSeries(_arr);
55+
ArraySetAsSeries(_arr, false);
56+
ArraySetAsSeries(_values, false);
57+
ArrayResize(_values, 0);
58+
ArrayCopy(_values, _arr);
59+
_values_size = ArraySize(_arr);
60+
ArraySetAsSeries(_arr, _was_series);
61+
ArraySetAsSeries(_values, _was_series);
62+
}
5363

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

8292
/**
8393
* Resizes storage to given size.

0 commit comments

Comments
 (0)