11#property link " https://www.earnforex.com/metatrader-indicators/trading-session-time/"
2- #property version " 1.01 "
2+ #property version " 1.02 "
33#property strict
44#property copyright " EarnForex.com - 2019-2023"
55#property description " Trading Session Time Indicator"
@@ -58,6 +58,8 @@ int StartMinute = 0;
5858int EndHour = 0 ;
5959int EndMinute = 0 ;
6060int BarsInChart = 0 ;
61+ datetime LatestSessionStart = 0 ;
62+ datetime LatestSessionEnd = 0 ;
6163
6264double CandleOpen [], CandleClose [], CandleHigh [], CandleLow [];
6365int ChartScale = WRONG_VALUE ;
@@ -87,6 +89,7 @@ int OnInit()
8789
8890 UpdateCandleWidth ();
8991 }
92+ else IndicatorBuffers (0 );
9093
9194 return INIT_SUCCEEDED ;
9295}
@@ -102,7 +105,7 @@ int OnCalculate(const int rates_total,
102105 const long &volume [],
103106 const int &spread [])
104107{
105- if (Bars != BarsInChart )
108+ if (Bars != BarsInChart ) // New bar or bars.
106109 {
107110 ArrayInitialize (CandleOpen , 0 );
108111 ArrayInitialize (CandleHigh , 0 );
@@ -114,6 +117,13 @@ int OnCalculate(const int rates_total,
114117 else DrawAreas ();
115118 BarsInChart = Bars ;
116119 }
120+ else // No new bars.
121+ {
122+ // Updates related to the current candle.
123+ if (DrawCandles ) UpdateCurrentCandlestick ();
124+ else if (TimeLineEnd == " " ) UpdateCurrentLine ();
125+ else UpdateCurrentArea ();
126+ }
117127 return rates_total ;
118128}
119129
@@ -193,7 +203,9 @@ void DrawLine(datetime LineTime)
193203 datetime EndTimeTmp = StringToTime (StringConcatenate (TimeYear (LineTime ), " ." , TimeMonth (LineTime ), " ." , TimeDay (LineTime ), " " , 23 , " :" , 59 ));
194204 int StartBar = iBarShift (Symbol (), PERIOD_CURRENT , StartTimeTmp );
195205 int EndBar = iBarShift (Symbol (), PERIOD_CURRENT , EndTimeTmp );
196- int BarsCount = StartBar - EndBar ;
206+ if (StartBar == EndBar ) return ; // Empty session.
207+ if ((EndBar != 0 ) || (iTime (Symbol (), PERIOD_CURRENT , 0 ) >= EndTimeTmp )) EndBar ++; // End bar itself shouldn't be included unless it's the latest bar that makes a part of the session.
208+ int BarsCount = StartBar - EndBar + 1 ;
197209 double HighPoint = High [iHighest (Symbol (), PERIOD_CURRENT , MODE_HIGH , BarsCount , EndBar )];
198210 string LabelName = IndicatorName + " -LABEL-" + IntegerToString (LineTime );
199211 ObjectCreate (0 , LabelName , OBJ_TEXT , 0 , LineTime , HighPoint );
@@ -204,11 +216,32 @@ void DrawLine(datetime LineTime)
204216 ObjectSetInteger (0 , LabelName , OBJPROP_ANCHOR , ANCHOR_LEFT_LOWER );
205217 ObjectSetString (0 , LabelName , OBJPROP_FONT , " Consolas" );
206218 ObjectSetInteger (0 , LabelName , OBJPROP_FONTSIZE , 10 );
207- string Text ;
208- if (SessionLabel != " " )
219+ string Text = SessionLabel ;
220+ if (ShowRange )
209221 {
210- Text += " " + SessionLabel ;
222+ double LowPoint = Low [iLowest (Symbol (), PERIOD_CURRENT , MODE_LOW , BarsCount , EndBar )];
223+ Text += " " + IntegerToString (int ((HighPoint - LowPoint ) / _Point ));
211224 }
225+ ObjectSetString (0 , LabelName , OBJPROP_TEXT , Text );
226+ if (EndTimeTmp > LatestSessionEnd ) LatestSessionEnd = EndTimeTmp ;
227+ if (LineTime > LatestSessionStart ) LatestSessionStart = LineTime ;
228+ }
229+ }
230+
231+ void UpdateCurrentLine ()
232+ {
233+ if (LatestSessionEnd == 0 ) return ; // Nothing to update.
234+ if (iTime (Symbol (), PERIOD_CURRENT , 0 ) >= LatestSessionEnd ) return ; // The current bar is outside the session.
235+
236+ if ((SessionLabel != " " ) || (ShowRange )) // Update the label if required.
237+ {
238+ int StartBar = iBarShift (Symbol (), PERIOD_CURRENT , LatestSessionStart );
239+ int EndBar = 0 ; // Always the latest bar.
240+ int BarsCount = StartBar - EndBar + 1 ;
241+ double HighPoint = iHigh (Symbol (), PERIOD_CURRENT , iHighest (Symbol (), PERIOD_CURRENT , MODE_HIGH , BarsCount , EndBar ));
242+ string LabelName = IndicatorName + " -LABEL-" + IntegerToString (LatestSessionStart );
243+ ObjectSetDouble (0 , LabelName , OBJPROP_PRICE , 0 , HighPoint );
244+ string Text = SessionLabel ;
212245 if (ShowRange )
213246 {
214247 double LowPoint = Low [iLowest (Symbol (), PERIOD_CURRENT , MODE_LOW , BarsCount , EndBar )];
@@ -251,7 +284,9 @@ void DrawArea(datetime Start, datetime End)
251284 string AreaName = IndicatorName + " -AREA-" + IntegerToString (Start );
252285 int StartBar = iBarShift (Symbol (), PERIOD_CURRENT , Start );
253286 int EndBar = iBarShift (Symbol (), PERIOD_CURRENT , End );
254- int BarsCount = StartBar - EndBar ;
287+ if (StartBar == EndBar ) return ; // Empty session.
288+ if ((EndBar != 0 ) || (iTime (Symbol (), PERIOD_CURRENT , 0 ) >= End )) EndBar ++; // End bar itself shouldn't be included unless it's the latest bar that makes a part of the session.
289+ int BarsCount = StartBar - EndBar + 1 ;
255290 double HighPoint = High [iHighest (Symbol (), PERIOD_CURRENT , MODE_HIGH , BarsCount , EndBar )];
256291 double LowPoint = Low [iLowest (Symbol (), PERIOD_CURRENT , MODE_LOW , BarsCount , EndBar )];
257292
@@ -275,17 +310,46 @@ void DrawArea(datetime Start, datetime End)
275310 ObjectSetInteger (0 , LabelName , OBJPROP_ANCHOR , ANCHOR_LEFT_LOWER );
276311 ObjectSetString (0 , LabelName , OBJPROP_FONT , " Consolas" );
277312 ObjectSetInteger (0 , LabelName , OBJPROP_FONTSIZE , 10 );
278- string Text ;
279- if (SessionLabel != " " )
280- {
281- Text += " " + SessionLabel ;
282- }
313+ string Text = SessionLabel ;
283314 if (ShowRange )
284315 {
285316 Text += " " + IntegerToString (int ((HighPoint - LowPoint ) / _Point ));
286317 }
287318 ObjectSetString (0 , LabelName , OBJPROP_TEXT , Text );
288319 }
320+ if (Start > LatestSessionStart ) LatestSessionStart = Start ;
321+ }
322+
323+ void UpdateCurrentArea ()
324+ {
325+ if (LatestSessionStart == 0 ) return ; // Nothing to update.
326+ string AreaName = IndicatorName + " -AREA-" + IntegerToString (LatestSessionStart );
327+ datetime End = (datetime )ObjectGetInteger (0 , AreaName , OBJPROP_TIME , 1 );
328+ if (iTime (Symbol (), PERIOD_CURRENT , 0 ) >= End ) return ; // The current bar is outside the session.
329+
330+ double prevHighPoint = ObjectGetDouble (0 , AreaName , OBJPROP_PRICE , 0 );
331+ double prevLowPoint = ObjectGetDouble (0 , AreaName , OBJPROP_PRICE , 1 );
332+ int StartBar = iBarShift (Symbol (), PERIOD_CURRENT , LatestSessionStart );
333+ int EndBar = 0 ; // Always the latest bar.
334+ int BarsCount = StartBar - EndBar + 1 ;
335+ double HighPoint = iHigh (Symbol (), PERIOD_CURRENT , iHighest (Symbol (), PERIOD_CURRENT , MODE_HIGH , BarsCount , EndBar ));
336+ double LowPoint = iLow (Symbol (), PERIOD_CURRENT , iLowest (Symbol (), PERIOD_CURRENT , MODE_LOW , BarsCount , EndBar ));
337+ if ((HighPoint > prevHighPoint ) || (LowPoint < prevLowPoint )) // Update is needed.
338+ {
339+ ObjectSetDouble (0 , AreaName , OBJPROP_PRICE , 0 , HighPoint );
340+ ObjectSetDouble (0 , AreaName , OBJPROP_PRICE , 1 , LowPoint );
341+ if ((SessionLabel != " " ) || (ShowRange )) // Update the label if required.
342+ {
343+ string LabelName = IndicatorName + " -LABEL-" + IntegerToString (LatestSessionStart );
344+ ObjectSetDouble (0 , LabelName , OBJPROP_PRICE , 0 , HighPoint );
345+ string Text = SessionLabel ;
346+ if (ShowRange )
347+ {
348+ Text += " " + IntegerToString (int ((HighPoint - LowPoint ) / _Point ));
349+ }
350+ ObjectSetString (0 , LabelName , OBJPROP_TEXT , Text );
351+ }
352+ }
289353}
290354
291355void OnChartEvent (const int id ,
@@ -358,7 +422,9 @@ void DrawCandlesticksSession(datetime Start, datetime End)
358422 string AreaName = IndicatorName + " -AREA-" + IntegerToString (Start );
359423 int StartBar = iBarShift (Symbol (), PERIOD_CURRENT , Start );
360424 int EndBar = iBarShift (Symbol (), PERIOD_CURRENT , End );
361- int BarsCount = StartBar - EndBar ;
425+ if (StartBar == EndBar ) return ; // Empty session.
426+ if ((EndBar != 0 ) || (iTime (Symbol (), PERIOD_CURRENT , 0 ) >= End )) EndBar ++; // End bar itself shouldn't be included unless it's the latest bar that makes a part of the session.
427+ int BarsCount = StartBar - EndBar + 1 ;
362428
363429 for (int i = StartBar ; i >= EndBar ; i --)
364430 {
@@ -388,11 +454,45 @@ void DrawCandlesticksSession(datetime Start, datetime End)
388454 ObjectSetInteger (0 , LabelName , OBJPROP_ANCHOR , ANCHOR_LEFT_LOWER );
389455 ObjectSetString (0 , LabelName , OBJPROP_FONT , " Consolas" );
390456 ObjectSetInteger (0 , LabelName , OBJPROP_FONTSIZE , 10 );
391- string Text ;
392- if (SessionLabel != " " )
457+ string Text = SessionLabel ;
458+ if (ShowRange )
393459 {
394- Text += " " + SessionLabel ;
460+ double LowPoint = Low [iLowest (Symbol (), PERIOD_CURRENT , MODE_LOW , BarsCount , EndBar )];
461+ Text += " " + IntegerToString (int ((HighPoint - LowPoint ) / _Point ));
395462 }
463+ ObjectSetString (0 , LabelName , OBJPROP_TEXT , Text );
464+ }
465+ if (Start > LatestSessionStart ) LatestSessionStart = Start ;
466+ if (End > LatestSessionEnd ) LatestSessionEnd = End ;
467+ }
468+
469+ void UpdateCurrentCandlestick ()
470+ {
471+ if (LatestSessionEnd == 0 ) return ; // Nothing to update.
472+ if (iTime (Symbol (), PERIOD_CURRENT , 0 ) >= LatestSessionEnd ) return ; // The current bar is outside the session.
473+
474+ if (Open [0 ] >= Close [0 ])
475+ {
476+ CandleLow [0 ] = Low [0 ];
477+ CandleHigh [0 ] = High [0 ];
478+ }
479+ else
480+ {
481+ CandleLow [0 ] = High [0 ];
482+ CandleHigh [0 ] = Low [0 ];
483+ }
484+ CandleOpen [0 ] = Open [0 ];
485+ CandleClose [0 ] = Close [0 ];
486+
487+ if ((SessionLabel != " " ) || (ShowRange )) // Update the label if required.
488+ {
489+ int StartBar = iBarShift (Symbol (), PERIOD_CURRENT , LatestSessionStart );
490+ int EndBar = 0 ; // Always the latest bar.
491+ int BarsCount = StartBar - EndBar + 1 ;
492+ double HighPoint = iHigh (Symbol (), PERIOD_CURRENT , iHighest (Symbol (), PERIOD_CURRENT , MODE_HIGH , BarsCount , EndBar ));
493+ string LabelName = IndicatorName + " -LABEL-" + IntegerToString (LatestSessionStart );
494+ ObjectSetDouble (0 , LabelName , OBJPROP_PRICE , 0 , HighPoint );
495+ string Text = SessionLabel ;
396496 if (ShowRange )
397497 {
398498 double LowPoint = Low [iLowest (Symbol (), PERIOD_CURRENT , MODE_LOW , BarsCount , EndBar )];
0 commit comments