1 | #property strict |
1 | #property strict |
2 | |
2 | |
3 | #define MAX_BUFFERS 7 |
3 | #define MAX_BUFFERS 7 |
4 | |
4 | |
5 | #property indicator_separate_window_window |
5 | #property indicator_separate_window_window |
6 | #property indicator_buffers MAX_BUFFERS |
6 | #property indicator_buffers MAX_BUFFERS |
7 | |
7 | |
8 | sinput int MaxCalcBars = PERIOD_D1 * 10; // Max Calculate Bars |
8 | sinput int MaxCalcBars = PERIOD_D1 * 10; // Max Calculate Bars |
9 | |
9 | |
10 | class INDICATOR |
10 | class INDICATOR |
11 | { |
11 | { |
12 | private: |
12 | private: |
13 | struct BUFFER |
13 | struct BUFFER |
14 | { |
14 | { |
15 | double Buffer[]; |
15 | double Buffer[]; |
16 | }; |
16 | }; |
17 | |
17 | |
18 | void Init( void ) |
18 | void Init( void ) |
19 | { |
19 | { |
20 | ArrayResize(Buffers, Size); |
20 | ArrayResize(Buffers, Size); |
21 | |
21 | |
22 | for (int i = 0; i < Size; i++) |
22 | for (int i = 0; i < Size; i++) |
23 | SetIndexBuffer(i, Buffers[i].Buffer); |
23 | SetIndexBuffer(i, Buffers[i].Buffer); |
24 | |
24 | |
25 | return; |
25 | return; |
26 | } |
26 | } |
27 | |
27 | |
28 | protected: |
28 | protected: |
29 | BUFFER Buffers[]; |
29 | BUFFER Buffers[]; |
30 | int Size; |
30 | int Size; |
31 | |
31 | |
32 | public: |
32 | public: |
33 | |
33 | |
34 | INDICATOR( const int &Colors[] ) |
34 | INDICATOR( const int &Colors[] ) |
35 | { |
35 | { |
36 | Size = MathMin(ArraySize(Colors), MAX_BUFFERS); |
36 | Size = MathMin(ArraySize(Colors), MAX_BUFFERS); |
37 | |
37 | |
38 | Init(); |
38 | Init(); |
39 | } |
39 | } |
40 | |
40 | |
41 | void BuffersSetAsSeries( const bool Flag ) |
41 | void BuffersSetAsSeries( const bool Flag ) |
42 | { |
42 | { |
43 | for (int i = 0; i < Size; i++) |
43 | for (int i = 0; i < Size; i++) |
44 | ArraySetAsSeries(Buffers[i].Buffer, Flag); |
44 | ArraySetAsSeries(Buffers[i].Buffer, Flag); |
45 | |
45 | |
46 | return; |
46 | return; |
47 | } |
47 | } |
48 | |
48 | |
49 | |
49 | |
50 | virtual int Calculate(const int rates_total, |
50 | virtual int Calculate(const int rates_total, |
51 | const int prev_calculated, |
51 | const int prev_calculated, |
52 | const datetime &time[], |
52 | const datetime &time[], |
53 | const double &open[], |
53 | const double &open[], |
54 | const double &high[], |
54 | const double &high[], |
55 | const double &low[], |
55 | const double &low[], |
56 | const double &close[], |
56 | const double &close[], |
57 | const long &tick_volume[], |
57 | const long &tick_volume[], |
58 | const long &volume[], |
58 | const long &volume[], |
59 | const int &spread[]) |
59 | const int &spread[]) |
60 | { |
60 | { |
61 | return(rates_total); |
61 | return(rates_total); |
62 | } |
62 | } |
63 | }; |
63 | }; |
64 | |
64 | |
65 | /*--------------------------------------------------------*/ |
65 | /*--------------------------------------------------------*/ |
66 | |
66 | |
67 | input int period = PERIOD_H1; // Period in bars |
67 | extern int period = PERIOD_H1; // Period in bars |
68 | |
68 | |
69 | #define EMPTY_CURRENCY "" |
69 | #define EMPTY_CURRENCY "" |
70 | #define MAX_DIGITS 8 |
70 | #define MAX_DIGITS 8 |
71 | |
71 | |
72 | class RELATION : INDICATOR |
72 | class RELATION : INDICATOR |
73 | { |
73 | { |
74 | private: |
74 | private: |
75 | struct SYMBOL |
75 | struct SYMBOL |
76 | { |
76 | { |
77 | string Name; |
77 | string Name; |
78 | bool Direction; |
78 | bool Direction; |
79 | |
79 | |
80 | void SetSymbol( const string Symb, const string BaseCurrency ) |
80 | void SetSymbol( const string Symb, const string BaseCurrency ) |
81 | { |
81 | { |
82 | Name = Symb; |
82 | Name = Symb; |
83 | |
83 | |
84 | Direction = (StringSubstr(Symb, 0, 3) == BaseCurrency); |
84 | Direction = (StringSubstr(Symb, 0, 3) == BaseCurrency); |
85 | |
85 | |
86 | return; |
86 | return; |
87 | } |
87 | } |
88 | |
88 | |
89 | double GetLogPrice( const datetime time ) |
89 | double GetLogPrice( const datetime time ) |
90 | { |
90 | { |
91 | return(MathLog(iClose(Name, Period(), iBarShift(Name, Period(), time)))); |
91 | return(MathLog(iClose(Name, Period(), iBarShift(Name, Period(), time)))); |
92 | } |
92 | } |
93 | |
93 | |
94 | double GetRelation( const datetime TimeLeft, const datetime TimeRight ) |
94 | double GetRelation( const datetime TimeLeft, const datetime TimeRight ) |
95 | { |
95 | { |
96 | double Res = GetLogPrice(TimeRight) - GetLogPrice(TimeLeft); |
96 | double Res = GetLogPrice(TimeRight) - GetLogPrice(TimeLeft); |
97 | |
97 | |
98 | if (Direction) |
98 | if (Direction) |
99 | Res = -Res; |
99 | Res = -Res; |
100 | |
100 | |
101 | return(Res); |
101 | return(Res); |
102 | } |
102 | } |
103 | }; |
103 | }; |
104 | |
104 | |
105 | SYMBOL Symbols[]; |
105 | SYMBOL Symbols[]; |
106 | |
106 | |
107 | string GetBaseCurrency( const string Symbol1, const string Symbol2 ) |
107 | string GetBaseCurrency( const string Symbol1, const string Symbol2 ) |
108 | { |
108 | { |
109 | string Currency = StringSubstr(Symbol1, 0, 3); |
109 | string Currency = StringSubstr(Symbol1, 0, 3); |
110 | |
110 | |
111 | if (StringFind(Symbol2, Currency) >= 0) |
111 | if (StringFind(Symbol2, Currency) >= 0) |
112 | return(Currency); |
112 | return(Currency); |
113 | |
113 | |
114 | Currency = StringSubstr(Symbol1, 3, 3); |
114 | Currency = StringSubstr(Symbol1, 3, 3); |
115 | |
115 | |
116 | if (StringFind(Symbol2, Currency) >= 0) |
116 | if (StringFind(Symbol2, Currency) >= 0) |
117 | return(Currency); |
117 | return(Currency); |
118 | |
118 | |
119 | return(EMPTY_CURRENCY); |
119 | return(EMPTY_CURRENCY); |
120 | } |
120 | } |
121 | |
121 | |
122 | public: |
122 | public: |
123 | RELATION( const string &SymbolList[], const int &Colors[] ) : INDICATOR(Colors) |
123 | RELATION( const string &SymbolList[], const int &Colors[] ) : INDICATOR(Colors) |
124 | { |
124 | { |
125 | string Currency1 = StringSubstr(Symbol(), 0, 3); |
125 | string Currency1 = StringSubstr(Symbol(), 0, 3); |
126 | string Currency2 = StringSubstr(Symbol(), 3, 3); |
126 | string Currency2 = StringSubstr(Symbol(), 3, 3); |
127 | |
127 | |
128 | string BaseCurrency = EMPTY_CURRENCY; |
128 | string BaseCurrency = EMPTY_CURRENCY; |
129 | |
129 | |
130 | if (Size > ArraySize(SymbolList)) |
130 | if (Size > ArraySize(SymbolList)) |
131 | { |
131 | { |
132 | Size = ArraySize(SymbolList); |
132 | Size = ArraySize(SymbolList); |
133 | |
133 | |
134 | ArrayResize(Buffers, Size); |
134 | ArrayResize(Buffers, Size); |
135 | } |
135 | } |
136 | |
136 | |
137 | ArrayResize(Symbols, Size); |
137 | ArrayResize(Symbols, Size); |
138 | |
138 | |
139 | if (Size > 1) |
139 | if (Size > 1) |
140 | BaseCurrency = GetBaseCurrency(SymbolList[0], SymbolList[1]); |
140 | BaseCurrency = GetBaseCurrency(SymbolList[0], SymbolList[1]); |
141 | |
141 | |
142 | if (Currency1 == BaseCurrency) |
142 | if (Currency1 == BaseCurrency) |
143 | Currency1 = EMPTY_CURRENCY; |
143 | Currency1 = EMPTY_CURRENCY; |
144 | else if (Currency2 == BaseCurrency) |
144 | else if (Currency2 == BaseCurrency) |
145 | Currency2 = EMPTY_CURRENCY; |
145 | Currency2 = EMPTY_CURRENCY; |
146 | |
146 | |
147 | IndicatorDigits(MAX_DIGITS); |
147 | IndicatorDigits(MAX_DIGITS); |
148 | |
148 | |
149 | for (int i = 0; i < Size; i++) |
149 | for (int i = 0; i < Size; i++) |
150 | { |
150 | { |
151 | if ((StringFind(SymbolList[i], Currency1) >= 0) || (StringFind(SymbolList[i], Currency2) >= 0)) |
151 | if ((StringFind(SymbolList[i], Currency1) >= 0) || (StringFind(SymbolList[i], Currency2) >= 0)) |
152 | SetIndexStyle(i, DRAW_LINE, EMPTY, 2, Colors[i]); |
152 | SetIndexStyle(i, DRAW_LINE, EMPTY, 2, Colors[i]); |
153 | else |
153 | else |
154 | SetIndexStyle(i, DRAW_LINE, EMPTY, 1, Colors[i]); |
154 | SetIndexStyle(i, DRAW_LINE, EMPTY, 1, Colors[i]); |
155 | |
155 | |
156 | SetIndexLabel(i, SymbolList[i]); |
156 | SetIndexLabel(i, SymbolList[i]); |
157 | |
157 | |
158 | Symbols[i].SetSymbol(SymbolList[i], BaseCurrency); |
158 | Symbols[i].SetSymbol(SymbolList[i], BaseCurrency); |
159 | } |
159 | } |
160 | |
160 | |
161 | BuffersSetAsSeries(FALSE); |
161 | BuffersSetAsSeries(FALSE); |
162 | |
162 | |
163 | return; |
163 | return; |
164 | } |
164 | } |
165 | |
165 | |
166 | virtual int Calculate(const int rates_total, |
166 | virtual int Calculate(const int rates_total, |
167 | const int prev_calculated, |
167 | const int prev_calculated, |
168 | const datetime &time[], |
168 | const datetime &time[], |
169 | const double &open[], |
169 | const double &open[], |
170 | const double &high[], |
170 | const double &high[], |
171 | const double &low[], |
171 | const double &low[], |
172 | const double &close[], |
172 | const double &close[], |
173 | const long &tick_volume[], |
173 | const long &tick_volume[], |
174 | const long &volume[], |
174 | const long &volume[], |
175 | const int &spread[]) |
175 | const int &spread[]) |
176 | { |
176 | { |
177 | ArraySetAsSeries(time, FALSE); |
177 | ArraySetAsSeries(time, FALSE); |
178 | |
178 | |
179 | const int Begin = MathMax(MathMax(prev_calculated - 1, rates_total - MaxCalcBars), period); |
179 | const int Begin = MathMax(MathMax(prev_calculated - 1, rates_total - MaxCalcBars), period); |
180 | const int SymbolsSize = ArraySize(Symbols); |
180 | const int SymbolsSize = ArraySize(Symbols); |
181 | |
181 | |
182 | for (int i = Begin; i < rates_total; i++) |
182 | for (int i = Begin; i < rates_total; i++) |
183 | for (int j = 0; j < SymbolsSize; j++) |
183 | for (int j = 0; j < SymbolsSize; j++) |
184 | Buffers[j].Buffer[i] = Symbols[j].GetRelation(time[i - period], time[i]); |
184 | Buffers[j].Buffer[i] = Symbols[j].GetRelation(time[i - period], time[i]); |
185 | |
185 | |
186 | return(rates_total); |
186 | return(rates_total); |
187 | } |
187 | } |
188 | }; |
188 | }; |
189 | |
189 | |
190 | /*--------------------------------------------------------*/ |
190 | /*--------------------------------------------------------*/ |
191 | |
191 | |
192 | INDICATOR* Relation; |
192 | INDICATOR* Relation; |
193 | |
193 | |
194 | void OnInit( void ) |
194 | void OnInit( void ) |
195 | { |
195 | { |
196 | const int Colors[] = {clrRed, clrBlue, clrSandyBrown, clrThistle, clrLime, clrSandyBrown, clrMagenta}; |
196 | const int Colors[] = {clrRed, clrBlue, clrSandyBrown, clrThistle, clrLime, clrSandyBrown, clrMagenta}; |
197 | const string SymbolList[] = {"EURUSD", "GBPUSD", "AUDUSD", "NZDUSD", "USDJPY", "USDCHF", "USDCAD"}; |
197 | const string SymbolList[] = {"EURUSD", "GBPUSD", "AUDUSD", "NZDUSD", "USDJPY", "USDCHF", "USDCAD"}; |
198 | |
198 | |
199 | Relation = new RELATION(SymbolList, Colors); |
199 | Relation = new RELATION(SymbolList, Colors); |
200 | |
200 | |
201 | return; |
201 | return; |
202 | } |
202 | } |
203 | |
203 | |
204 | void OnDeinit( const int reason ) |
204 | void OnDeinit( const int reason ) |
205 | { |
205 | { |
206 | delete Relation; |
206 | delete Relation; |
207 | |
207 | |
208 | return; |
208 | return; |
209 | } |
209 | } |
210 | |
210 | |
211 | int OnCalculate(const int rates_total, |
211 | int OnCalculate(const int rates_total, |
212 | const int prev_calculated, |
212 | const int prev_calculated, |
213 | const datetime &time[], |
213 | const datetime &time[], |
214 | const double &open[], |
214 | const double &open[], |
215 | const double &high[], |
215 | const double &high[], |
216 | const double &low[], |
216 | const double &low[], |
217 | const double &close[], |
217 | const double &close[], |
218 | const long &tick_volume[], |
218 | const long &tick_volume[], |
219 | const long &volume[], |
219 | const long &volume[], |
220 | const int &spread[]) |
220 | const int &spread[]) |
221 | { |
221 | { |
222 | return(Relation.Calculate(rates_total, prev_calculated, time, open, high, low, close, tick_volume, volume, spread)); |
222 | return(Relation.Calculate(rates_total, prev_calculated, time, open, high, low, close, tick_volume, volume, spread)); |
| |
223 | }
|
| |
224 |
|
| |
225 | // for ChangeInput: добавление в конце исходника
|
| |
226 | #include <ChangeInput.mqh>
|
| |
227 |
|
| |
228 | void OnChartEvent( const int id, const long& lparam, const double& dparam, const string& sparam )
|
| |
229 | {
|
| |
230 | EVENTBASE::MyEvent(id, lparam, dparam, sparam); // for ChangeInput: в OnChartEvent добавить эту строчку
|
| |
231 |
|
| |
232 | return;
|
| |
233 | }
|
| |
234 |
|
| |
235 | void CHANGEINPUT::MyInit( void )
|
| |
236 | {
|
| |
237 | SetGetParameter("Period in bars", period);
|
| |
238 |
|
| |
239 | return;
|
223 | } |
240 | } |