44//| https://www.earnforex.com/ |
55//+------------------------------------------------------------------+
66#property copyright " Copyright © 2025, www.EarnForex.com"
7- #property link " https://www.earnforex.com/metatrader- indicators/SwitchTimeframesKeys/"
8- #property version " 1.00 "
7+ #property link " https://www.earnforex.com/indicators/SwitchTimeframesKeys/"
8+ #property version " 1.01 "
99#property strict
1010
1111#property description " Switches timeframes using keyboard shortcuts."
@@ -29,6 +29,9 @@ input string MN = "9";
2929input string SwitchDown = " Z" ;
3030input string SwitchUp = " X" ;
3131input string SwitchThrough = " M1, M5, M15, M30, H1, H4, D1, W1, MN" ;
32+ input string ____Configuration = " === Configuration ===" ;
33+ input bool ChangeAllCharts = false ;
34+ input bool EnableSignature = true ;
3235
3336ENUM_TIMEFRAMES TF_Array [];
3437uchar MainKey_M1 = 0 , MainKey_M5 = 0 , MainKey_M15 = 0 , MainKey_M30 = 0 , MainKey_H1 = 0 , MainKey_H4 = 0 , MainKey_D1 = 0 , MainKey_W1 = 0 , MainKey_MN = 0 , MainKey_SwitchDown = 0 , MainKey_SwitchUp = 0 ;
@@ -62,6 +65,16 @@ void OnInit()
6265 else MainKey_SwitchUp = 0 ;
6366
6467 PrepareSwitchThroughArray ();
68+
69+ if (EnableSignature ) ShowSignature ();
70+ }
71+
72+ void OnDeinit (const int reason )
73+ {
74+ if (EnableSignature )
75+ {
76+ ObjectDelete (ChartID (), " STK_Signature" );
77+ }
6578}
6679
6780// A dummy function because everything is handled in OnChartEvent().
@@ -86,147 +99,108 @@ void OnChartEvent(const int id,
8699 const string &sparam )
87100{
88101 if (id != CHARTEVENT_KEYDOWN ) return ;
89-
90- if ((MainKey_M1 != 0 ) && (lparam == MainKey_M1 )
102+
103+ // Get Unicode key value.
104+ short key = TranslateKey ((int )lparam );
105+ // In case of falire, use raw value.
106+ if (key == -1 ) key = (short )lparam ;
107+
108+ if ((MainKey_M1 != 0 ) && (key == MainKey_M1 )
91109 && ((((!ShiftRequired_M1 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) >= 0 )) || ((ShiftRequired_M1 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) < 0 ))) // Shift
92110 && (((!CtrlRequired_M1 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) >= 0 )) || ((CtrlRequired_M1 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) < 0 )))) // Control
93111 )
94112 {
95- ChartSetSymbolPeriod ( ChartID (), Symbol (), PERIOD_M1 );
113+ ChangeToSpecificTimeFrame ( PERIOD_M1 );
96114 }
97- else if ((MainKey_M5 != 0 ) && (lparam == MainKey_M5 )
115+ else if ((MainKey_M5 != 0 ) && (key == MainKey_M5 )
98116 && ((((!ShiftRequired_M5 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) >= 0 )) || ((ShiftRequired_M5 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) < 0 ))) // Shift
99117 && (((!CtrlRequired_M5 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) >= 0 )) || ((CtrlRequired_M5 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) < 0 )))) // Control
100118 )
101119 {
102- ChartSetSymbolPeriod ( ChartID (), Symbol (), PERIOD_M5 );
120+ ChangeToSpecificTimeFrame ( PERIOD_M5 );
103121 }
104- else if ((MainKey_M15 != 0 ) && (lparam == MainKey_M15 )
122+ else if ((MainKey_M15 != 0 ) && (key == MainKey_M15 )
105123 && ((((!ShiftRequired_M15 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) >= 0 )) || ((ShiftRequired_M15 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) < 0 ))) // Shift
106124 && (((!CtrlRequired_M15 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) >= 0 )) || ((CtrlRequired_M15 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) < 0 )))) // Control
107125 )
108126 {
109- ChartSetSymbolPeriod ( ChartID (), Symbol (), PERIOD_M15 );
127+ ChangeToSpecificTimeFrame ( PERIOD_M15 );
110128 }
111- else if ((MainKey_M30 != 0 ) && (lparam == MainKey_M30 )
129+ else if ((MainKey_M30 != 0 ) && (key == MainKey_M30 )
112130 && ((((!ShiftRequired_M30 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) >= 0 )) || ((ShiftRequired_M30 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) < 0 ))) // Shift
113131 && (((!CtrlRequired_M30 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) >= 0 )) || ((CtrlRequired_M30 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) < 0 )))) // Control
114132 )
115133 {
116- ChartSetSymbolPeriod ( ChartID (), Symbol (), PERIOD_M30 );
134+ ChangeToSpecificTimeFrame ( PERIOD_M30 );
117135 }
118- else if ((MainKey_H1 != 0 ) && (lparam == MainKey_H1 )
136+ else if ((MainKey_H1 != 0 ) && (key == MainKey_H1 )
119137 && ((((!ShiftRequired_H1 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) >= 0 )) || ((ShiftRequired_H1 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) < 0 ))) // Shift
120138 && (((!CtrlRequired_H1 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) >= 0 )) || ((CtrlRequired_H1 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) < 0 )))) // Control
121139 )
122140 {
123- ChartSetSymbolPeriod ( ChartID (), Symbol (), PERIOD_H1 );
141+ ChangeToSpecificTimeFrame ( PERIOD_H1 );
124142 }
125- else if ((MainKey_H4 != 0 ) && (lparam == MainKey_H4 )
143+ else if ((MainKey_H4 != 0 ) && (key == MainKey_H4 )
126144 && ((((!ShiftRequired_H4 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) >= 0 )) || ((ShiftRequired_H4 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) < 0 ))) // Shift
127145 && (((!CtrlRequired_H4 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) >= 0 )) || ((CtrlRequired_H4 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) < 0 )))) // Control
128146 )
129147 {
130- ChartSetSymbolPeriod ( ChartID (), Symbol (), PERIOD_H4 );
148+ ChangeToSpecificTimeFrame ( PERIOD_H4 );
131149 }
132- else if ((MainKey_D1 != 0 ) && (lparam == MainKey_D1 )
150+ else if ((MainKey_D1 != 0 ) && (key == MainKey_D1 )
133151 && ((((!ShiftRequired_D1 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) >= 0 )) || ((ShiftRequired_D1 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) < 0 ))) // Shift
134152 && (((!CtrlRequired_D1 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) >= 0 )) || ((CtrlRequired_D1 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) < 0 )))) // Control
135153 )
136154 {
137- ChartSetSymbolPeriod ( ChartID (), Symbol (), PERIOD_D1 );
155+ ChangeToSpecificTimeFrame ( PERIOD_D1 );
138156 }
139- else if ((MainKey_W1 != 0 ) && (lparam == MainKey_W1 )
157+ else if ((MainKey_W1 != 0 ) && (key == MainKey_W1 )
140158 && ((((!ShiftRequired_W1 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) >= 0 )) || ((ShiftRequired_W1 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) < 0 ))) // Shift
141159 && (((!CtrlRequired_W1 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) >= 0 )) || ((CtrlRequired_W1 ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) < 0 )))) // Control
142160 )
143161 {
144- ChartSetSymbolPeriod ( ChartID (), Symbol (), PERIOD_W1 );
162+ ChangeToSpecificTimeFrame ( PERIOD_W1 );
145163 }
146- else if ((MainKey_MN != 0 ) && (lparam == MainKey_MN )
164+ else if ((MainKey_MN != 0 ) && (key == MainKey_MN )
147165 && ((((!ShiftRequired_MN ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) >= 0 )) || ((ShiftRequired_MN ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) < 0 ))) // Shift
148166 && (((!CtrlRequired_MN ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) >= 0 )) || ((CtrlRequired_MN ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) < 0 )))) // Control
149167 )
150168 {
151- ChartSetSymbolPeriod ( ChartID (), Symbol (), PERIOD_MN1 );
169+ ChangeToSpecificTimeFrame ( PERIOD_MN1 );
152170 }
153- else if ((MainKey_SwitchDown != 0 ) && (lparam == MainKey_SwitchDown )
171+ else if ((MainKey_SwitchDown != 0 ) && (key == MainKey_SwitchDown )
154172 && ((((!ShiftRequired_SwitchDown ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) >= 0 )) || ((ShiftRequired_SwitchDown ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) < 0 ))) // Shift
155173 && (((!CtrlRequired_SwitchDown ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) >= 0 )) || ((CtrlRequired_SwitchDown ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) < 0 )))) // Control
156174 )
157175 {
158- if (ArraySize (TF_Array ) == 0 ) return ;
159- bool tf_found = false ;
160- for (int i = 0 ; i < ArraySize (TF_Array ); i ++)
176+ if (ChangeAllCharts )
161177 {
162- if ( Period () == TF_Array [ i ]) // Easy - the TF has been found.
178+ for ( long chart = ChartFirst (); chart >= 0 ; chart = ChartNext ( chart ))
163179 {
164- if (i > 0 ) i --;
165- else i = ArraySize (TF_Array ) - 1 ;
166- ChartSetSymbolPeriod (ChartID (), Symbol (), TF_Array [i ]);
167- tf_found = true ;
168- break ;
169- }
170- }
171- if (!tf_found ) // Difficult - TF not found.
172- {
173- // Find the first TF > current one:
174- for (int i = 0 ; i < ArraySize (TF_Array ); i ++)
175- {
176- if (PeriodSeconds () < PeriodSeconds (TF_Array [i ]))
180+ if (chart != ChartID ())
177181 {
178- if (i > 0 ) i --;
179- else i = ArraySize (TF_Array ) - 1 ;
180- ChartSetSymbolPeriod (ChartID (), Symbol (), TF_Array [i ]);
181- tf_found = true ;
182- break ;
182+ ChartSetSymbolPeriod (chart , ChartSymbol (chart ), GetLowerTimeFrame (ChartPeriod (chart )));
183183 }
184184 }
185- if (!tf_found ) // If once again not found - i.e., all TFs are below the current one:
186- {
187- // Switch to the last one.
188- ChartSetSymbolPeriod (ChartID (), Symbol (), TF_Array [ArraySize (TF_Array ) - 1 ]);
189- }
190185 }
186+ ChartSetSymbolPeriod (ChartID (), Symbol (), GetLowerTimeFrame ((ENUM_TIMEFRAMES )Period ()));
191187 }
192- else if ((MainKey_SwitchUp != 0 ) && (lparam == MainKey_SwitchUp )
188+ else if ((MainKey_SwitchUp != 0 ) && (key == MainKey_SwitchUp )
193189 && ((((!ShiftRequired_SwitchUp ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) >= 0 )) || ((ShiftRequired_SwitchUp ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_SHIFT ) < 0 ))) // Shift
194190 && (((!CtrlRequired_SwitchUp ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) >= 0 )) || ((CtrlRequired_SwitchUp ) && (TerminalInfoInteger (TERMINAL_KEYSTATE_CONTROL ) < 0 )))) // Control
195191 )
196192 {
197- if (ArraySize (TF_Array ) == 0 ) return ;
198- bool tf_found = false ;
199- for (int i = 0 ; i < ArraySize (TF_Array ); i ++)
193+ if (ChangeAllCharts )
200194 {
201- if ( Period () == TF_Array [ i ]) // Easy - the TF has been found.
195+ for ( long chart = ChartFirst (); chart >= 0 ; chart = ChartNext ( chart ))
202196 {
203- if (i < ArraySize (TF_Array ) - 1 ) i ++;
204- else i = 0 ;
205- ChartSetSymbolPeriod (ChartID (), Symbol (), TF_Array [i ]);
206- tf_found = true ;
207- break ;
208- }
209- }
210- if (!tf_found ) // Difficult - TF not found.
211- {
212- // Find the first TF < current one:
213- for (int i = ArraySize (TF_Array ) - 1 ; i >= 0 ; i --)
214- {
215- if (PeriodSeconds () > PeriodSeconds (TF_Array [i ]))
197+ if (chart != ChartID ())
216198 {
217- if (i < ArraySize (TF_Array ) - 1 ) i ++;
218- else i = 0 ;
219- ChartSetSymbolPeriod (ChartID (), Symbol (), TF_Array [i ]);
220- tf_found = true ;
221- break ;
199+ ChartSetSymbolPeriod (chart , ChartSymbol (chart ), GetUpperTimeFrame (ChartPeriod (chart )));
222200 }
223201 }
224- if (!tf_found ) // If once again not found - i.e., all TFs are above the current one:
225- {
226- // Switch to the first one.
227- ChartSetSymbolPeriod (ChartID (), Symbol (), TF_Array [0 ]);
228- }
229202 }
203+ ChartSetSymbolPeriod (ChartID (), Symbol (), GetUpperTimeFrame ((ENUM_TIMEFRAMES )Period ()));
230204 }
231205}
232206
@@ -248,13 +222,19 @@ void DissectHotKeyCombination(const string hotkey, bool &shift_required, bool &c
248222 else if (keys [i ] == " CTRL" ) ctrl_required = true ;
249223 }
250224 }
251- StringToUpper (keys [n - 1 ]);
252- if (keys [n - 1 ] == " TAB" ) main_key = 9 ;
253- else if ((keys [n - 1 ] == " ESC" ) || (keys [n - 1 ] == " ESCAPE" )) main_key = 27 ;
254- else if ((keys [n - 1 ] == " BACKSPACE" ) || (keys [n - 1 ] == " BACK" ) || (keys [n - 1 ] == " BS" ) || (keys [n - 1 ] == " BKSP" )) main_key = 8 ;
255- else if ((keys [n - 1 ] == " CAPS" ) || (keys [n - 1 ] == " CAPS LOCK" ) || (keys [n - 1 ] == " CAPSLOCK" ) || (keys [n - 1 ] == " CAPSLK" )) main_key = 20 ;
225+ StringToLower (keys [n - 1 ]);
226+ StringReplace (keys [n - 1 ], " " , " " ); // Remove spaces.
227+ if (keys [n - 1 ] == " tab" ) main_key = 9 ;
228+ else if ((keys [n - 1 ] == " esc" ) || (keys [n - 1 ] == " escape" )) main_key = 27 ;
229+ else if ((keys [n - 1 ] == " backspace" ) || (keys [n - 1 ] == " back" ) || (keys [n - 1 ] == " bs" ) || (keys [n - 1 ] == " bksp" )) main_key = 8 ;
230+ else if ((keys [n - 1 ] == " caps" ) || (keys [n - 1 ] == " capslock" ) || (keys [n - 1 ] == " capslk" )) main_key = 20 ;
231+ else if ((keys [n - 1 ] == " uparrow" ) || (keys [n - 1 ] == " arrowup" )) main_key = 38 ;
232+ else if ((keys [n - 1 ] == " downarrow" ) || (keys [n - 1 ] == " arrowdown" ) || (keys [n - 1 ] == " arrowdn" ) || (keys [n - 1 ] == " dnarrow" )) main_key = 40 ;
233+ else if ((keys [n - 1 ] == " leftarrow" ) || (keys [n - 1 ] == " arrowleft" )) main_key = 37 ;
234+ else if ((keys [n - 1 ] == " rightarrow" ) || (keys [n - 1 ] == " arrowright" )) main_key = 39 ;
235+ else if ((keys [n - 1 ] == " pageup" ) || (keys [n - 1 ] == " pgup" )) main_key = 33 ;
236+ else if ((keys [n - 1 ] == " pagedown" ) || (keys [n - 1 ] == " pgdown" ) || (keys [n - 1 ] == " pagedn" ) || (keys [n - 1 ] == " pgdn" )) main_key = 34 ;
256237 else main_key = (uchar )StringGetCharacter (keys [n - 1 ], 0 );
257- if (main_key == 96 ) main_key = 192 ; // A hack to use ` as a hotkey.
258238}
259239
260240void PrepareSwitchThroughArray ()
@@ -297,4 +277,88 @@ ENUM_TIMEFRAMES StringToTimeframe(string s)
297277 if ((s == " M1" ) || (s == " 1M" ) || (s == " PERIOD_M1" )) return PERIOD_M1 ;
298278 return PERIOD_CURRENT ;
299279}
280+
281+ void ChangeToSpecificTimeFrame (ENUM_TIMEFRAMES tf )
282+ {
283+ if (ChangeAllCharts )
284+ {
285+ for (long chart = ChartFirst (); chart >= 0 ; chart = ChartNext (chart ))
286+ {
287+ if (chart != ChartID ())
288+ {
289+ ChartSetSymbolPeriod (chart , ChartSymbol (chart ), tf );
290+ }
291+ }
292+ }
293+ ChartSetSymbolPeriod (ChartID (), Symbol (), tf );
294+ }
295+
296+ ENUM_TIMEFRAMES GetLowerTimeFrame (ENUM_TIMEFRAMES current_tf )
297+ {
298+ if (ArraySize (TF_Array ) == 0 ) return current_tf ;
299+ for (int i = 0 ; i < ArraySize (TF_Array ); i ++)
300+ {
301+ if (current_tf == TF_Array [i ]) // Easy - the TF has been found.
302+ {
303+ if (i > 0 ) i --;
304+ else i = ArraySize (TF_Array ) - 1 ;
305+ return TF_Array [i ];
306+ }
307+ }
308+ // Find the first TF > current one:
309+ for (int i = 0 ; i < ArraySize (TF_Array ); i ++)
310+ {
311+ if (PeriodSeconds (current_tf ) < PeriodSeconds (TF_Array [i ]))
312+ {
313+ if (i > 0 ) i --;
314+ else i = ArraySize (TF_Array ) - 1 ;
315+ return TF_Array [i ];
316+ }
317+ }
318+ // Return the last one in the array.
319+ return TF_Array [ArraySize (TF_Array ) - 1 ];
320+ }
321+
322+ ENUM_TIMEFRAMES GetUpperTimeFrame (ENUM_TIMEFRAMES current_tf )
323+ {
324+ if (ArraySize (TF_Array ) == 0 ) return current_tf ;
325+ for (int i = 0 ; i < ArraySize (TF_Array ); i ++)
326+ {
327+ if (current_tf == TF_Array [i ]) // Easy - the TF has been found.
328+ {
329+ if (i < ArraySize (TF_Array ) - 1 ) i ++;
330+ else i = 0 ;
331+ return TF_Array [i ];
332+ }
333+ }
334+ // Find the first TF < current one:
335+ for (int i = ArraySize (TF_Array ) - 1 ; i >= 0 ; i --)
336+ {
337+ if (PeriodSeconds (current_tf ) > PeriodSeconds (TF_Array [i ]))
338+ {
339+ if (i < ArraySize (TF_Array ) - 1 ) i ++;
340+ else i = 0 ;
341+ return TF_Array [i ];
342+ }
343+ }
344+ // Return the first one in the array.
345+ return TF_Array [0 ];
346+ }
347+
348+ void ShowSignature ()
349+ {
350+ ObjectCreate (ChartID (), " STK_Signature" , OBJ_LABEL , 0 , 0 , 0 );
351+ ObjectSetString (ChartID (), " STK_Signature" , OBJPROP_TEXT , " STK" );
352+ ObjectSetInteger (ChartID (), " STK_Signature" , OBJPROP_CORNER , CORNER_LEFT_LOWER );
353+ ObjectSetInteger (ChartID (), " STK_Signature" , OBJPROP_XDISTANCE , 3 );
354+ ObjectSetInteger (ChartID (), " STK_Signature" , OBJPROP_YDISTANCE , 15 );
355+ ObjectSetString (ChartID (), " STK_Signature" , OBJPROP_FONT , " Verdana" );
356+ ObjectSetInteger (ChartID (), " STK_Signature" , OBJPROP_FONTSIZE , 8 );
357+ ObjectSetInteger (ChartID (), " STK_Signature" , OBJPROP_COLOR , clrDarkGray );
358+ ObjectSetInteger (ChartID (), " STK_Signature" , OBJPROP_SELECTABLE , false );
359+ ObjectSetInteger (ChartID (), " STK_Signature" , OBJPROP_SELECTED , false );
360+ ObjectSetInteger (ChartID (), " STK_Signature" , OBJPROP_HIDDEN , true );
361+ ObjectSetInteger (ChartID (), " STK_Signature" , OBJPROP_BACK , true );
362+ ObjectSetString (ChartID (), " STK_Signature" , OBJPROP_TOOLTIP , " Switch Timeframes Keys is running." );
363+ }
300364//+------------------------------------------------------------------+
0 commit comments