forked from EA31337/EA31337-classes
-
Notifications
You must be signed in to change notification settings - Fork 0
/
IndicatorDataTest.mq4
218 lines (186 loc) · 6.81 KB
/
IndicatorDataTest.mq4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
//+------------------------------------------------------------------+
//| EA31337 framework |
//| Copyright 2016-2019, 31337 Investments Ltd |
//| https://github.com/EA31337 |
//+------------------------------------------------------------------+
/*
* This file is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @file
* Test functionality of IndicatorData class.
*/
// Includes.
#include "../IndicatorData.mqh"
// User inputs.
#ifdef __input__ input #endif string __MA_Parameters__ = "-- Settings for the Moving Average indicator --"; // >>> MA <<<
#ifdef __input__ input #endif int MA_Period_Fast = 14; // Period Fast
#ifdef __input__ input #endif int MA_Period_Medium = 20; // Period Medium
#ifdef __input__ input #endif int MA_Period_Slow = 48; // Period Slow
#ifdef __input__ input #endif double MA_Period_Ratio = 1.0; // Period ratio between timeframes (0.5-1.5)
#ifdef __input__ input #endif int MA_Shift = 0; // Shift
#ifdef __input__ input #endif int MA_Shift_Fast = 0; // Shift Fast (+1)
#ifdef __input__ input #endif int MA_Shift_Medium = 0; // Shift Medium (+1)
#ifdef __input__ input #endif int MA_Shift_Slow = 1; // Shift Slow (+1)
#ifdef __input__ input #endif int MA_Shift_Far = 4; // Shift Far (+2)
#ifdef __input__ input #endif ENUM_MA_METHOD MA_Method = 1; // MA Method
#ifdef __input__ input #endif ENUM_APPLIED_PRICE MA_Applied_Price = 3; // Applied Price
class I_MA : public IndicatorData {
protected:
// Indicator Buffers.
enum ENUM_MA_MODE {
MODE_MA_FAST = 0,
MODE_MA_MEDIUM = 1,
MODE_MA_SLOW = 2,
MAX_OF_ENUM_MA_MODE //Buffers count
};
public:
/**
* Class constructor.
*/
void I_MA() : IndicatorData("Custom MA Indicator", MAX_OF_ENUM_MA_MODE) {}
/**
* Returns the indicator value.
*
* @docs
* - https://docs.mql4.com/indicators/ima
* - https://www.mql5.com/en/docs/indicators/ima
*/
static double iMA(
string _symbol,
ENUM_TIMEFRAMES _tf,
uint _ma_period,
int _ma_shift,
ENUM_MA_METHOD _ma_method, // (MT4/MT5): MODE_SMA, MODE_EMA, MODE_SMMA, MODE_LWMA
ENUM_APPLIED_PRICE _applied_price, // (MT4/MT5): PRICE_CLOSE, PRICE_OPEN, PRICE_HIGH, PRICE_LOW, PRICE_MEDIAN, PRICE_TYPICAL, PRICE_WEIGHTED
int _shift = 0
) {
#ifdef __MQL4__
return ::iMA(_symbol, _tf, _ma_period, _ma_shift, _ma_method, _applied_price, _shift);
#else // __MQL5__
double _res[];
int _handle = ::iMA(_symbol, _tf, _ma_period, _ma_shift, _ma_method, _applied_price);
return CopyBuffer(_handle, 0, _shift, 1, _res) > 0 ? _res[0] : EMPTY_VALUE;
#endif
}
double iMA(
uint _ma_period,
int _ma_shift,
ENUM_MA_METHOD _ma_method,
ENUM_APPLIED_PRICE _applied_price,
int _shift = 0) {
double _value = iMA(GetSymbol(), GetTf(), _ma_period, _ma_shift, _ma_method, _applied_price, _shift);
CheckLastError();
return _value;
}
/**
* Get period value from settings.
*/
int GetPeriod(ENUM_MA_MODE _ma_type) {
switch (_ma_type) {
default:
case MODE_MA_FAST: return MA_Period_Fast;
case MODE_MA_MEDIUM: return MA_Period_Medium;
case MODE_MA_SLOW: return MA_Period_Slow;
}
}
/**
* Get shift value from settings.
*/
int GetShift(ENUM_MA_MODE _ma_type) {
switch (_ma_type) {
default:
case MODE_MA_FAST: return MA_Shift_Fast;
case MODE_MA_MEDIUM: return MA_Shift_Medium;
case MODE_MA_SLOW: return MA_Shift_Slow;
}
}
/**
* Get method value from settings.
*/
ENUM_MA_METHOD GetMethod(ENUM_MA_MODE _ma_type) {
switch (_ma_type) {
default:
case MODE_MA_FAST: return MA_Method;
case MODE_MA_MEDIUM: return MA_Method;
case MODE_MA_SLOW: return MA_Method;
}
}
/**
* Get applied price value from settings.
*/
ENUM_APPLIED_PRICE GetAppliedPrice(ENUM_MA_MODE _ma_type) {
switch (_ma_type) {
default:
case MODE_MA_FAST: return MA_Applied_Price;
case MODE_MA_MEDIUM: return MA_Applied_Price;
case MODE_MA_SLOW: return MA_Applied_Price;
}
}
/**
* Calculates the Moving Average indicator.
*/
bool Update(int shift = CURR) {
bool _res = true;
double _ma_value;
for (ENUM_MA_MODE mode = 0; mode <= MODE_MA_SLOW; mode++) {
_ma_value = iMA(GetSymbol(), GetTf(), GetPeriod(mode), GetShift(mode), GetMethod(mode), GetAppliedPrice(mode), shift);
_res &= Add(_ma_value, mode, shift);
}
return _res;
}
};
//////////////////////////////////////////////////////////////////////////
// create a custom mt4 indicator to show values on mt4 chart
//////////////////////////////////////////////////////////////////////////
#property indicator_chart_window
#property indicator_buffers MAX_OF_ENUM_MA_MODE
double FastMa[];
double MediumMa[];
double SlowMa[];
I_MA myMa;
/**
* Implements OnInit().
*/
int OnInit() {
IndicatorBuffers(MAX_OF_ENUM_MA_MODE);
SetIndexBuffer(MODE_MA_FAST, FastMa);
SetIndexBuffer(MODE_MA_MEDIUM, MediumMa);
SetIndexBuffer(MODE_MA_SLOW, SlowMa);
SetIndexStyle(MODE_MA_FAST, DRAW_LINE, STYLE_SOLID, 1, clrRed);
SetIndexStyle(MODE_MA_MEDIUM, DRAW_LINE, STYLE_SOLID, 1, clrGreen);
SetIndexStyle(MODE_MA_SLOW, DRAW_LINE, STYLE_SOLID, 1, clrGreen);
return (INIT_SUCCEEDED);
}
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
uint start_at = GetTickCount();
int oldest_bar = rates_total - prev_calculated - 1;
for(int i = oldest_bar; i >= 0; i--) {
bool ok = myMa.Update(i);
if (!ok) continue;
FastMa[i] = myMa.GetDouble(MODE_MA_FAST, i);
MediumMa[i] = myMa.GetDouble(MODE_MA_MEDIUM, i);
SlowMa[i] = myMa.GetDouble(MODE_MA_SLOW, i);
}
PrintFormat("elapse %dms", GetTickCount() - start_at);
return(rates_total);
}