﻿//+------------------------------------------------------------------+
//|                                         TimeBucketAnalyzer.mqh   |
//|               Intraday Return Heatmap — Time Decomposition Layer |
//+------------------------------------------------------------------+
#ifndef TIME_BUCKET_ANALYZER_MQH
#define TIME_BUCKET_ANALYZER_MQH

//+------------------------------------------------------------------+
//| CTimeBucketAnalyzer                                              |
//| Extracts the hour-of-day (0-23) and day-of-week index (0-4,      |
//| Monday=0 through Friday=4) from a bar timestamp.                 |
//| Weekend timestamps (Saturday and Sunday) are rejected.           |
//+------------------------------------------------------------------+
class CTimeBucketAnalyzer
  {
public:
                     CTimeBucketAnalyzer(void);
                    ~CTimeBucketAnalyzer(void);

   static bool       Decompose(datetime bar_time,
                               int &out_day_index,
                               int &out_hour_index);

   static bool       IsWeekend(datetime bar_time);
   static string     DayName(int day_index);
  };

//+------------------------------------------------------------------+
//| Constructor                                                      |
//+------------------------------------------------------------------+
CTimeBucketAnalyzer::CTimeBucketAnalyzer(void)
  {
  }

//+------------------------------------------------------------------+
//| Destructor                                                       |
//+------------------------------------------------------------------+
CTimeBucketAnalyzer::~CTimeBucketAnalyzer(void)
  {
  }

//+------------------------------------------------------------------+
//| Decompose a timestamp into day and hour bucket indices           |
//+------------------------------------------------------------------+
bool CTimeBucketAnalyzer::Decompose(datetime bar_time,
                                    int &out_day_index,
                                    int &out_hour_index)
  {
   out_day_index  = -1;
   out_hour_index = -1;

//--- reject weekend bars before further processing
   if(IsWeekend(bar_time))
      return(false);

//--- decompose timestamp into calendar components
   MqlDateTime dt;
   TimeToStruct(bar_time, dt);

//--- extract hour of day directly from struct
   out_hour_index = dt.hour;

//--- day_of_week: Sunday=0, Monday=1 ... Saturday=6
   switch(dt.day_of_week)
     {
      case 1:
         out_day_index = 0;
         break; // Monday
      case 2:
         out_day_index = 1;
         break; // Tuesday
      case 3:
         out_day_index = 2;
         break; // Wednesday
      case 4:
         out_day_index = 3;
         break; // Thursday
      case 5:
         out_day_index = 4;
         break; // Friday
      default:
         return(false);
     }

   return(true);
  }

//+------------------------------------------------------------------+
//| Return true if the timestamp falls on a weekend                  |
//+------------------------------------------------------------------+
bool CTimeBucketAnalyzer::IsWeekend(datetime bar_time)
  {
   MqlDateTime dt;
   TimeToStruct(bar_time, dt);
   return(dt.day_of_week == 0 || dt.day_of_week == 6); // Sunday=0, Saturday=6
  }

//+------------------------------------------------------------------+
//| Return the display name for a day index (0=Monday..4=Friday)     |
//+------------------------------------------------------------------+
string CTimeBucketAnalyzer::DayName(int day_index)
  {
   switch(day_index)
     {
      case 0:
         return("Monday");
      case 1:
         return("Tuesday");
      case 2:
         return("Wednesday");
      case 3:
         return("Thursday");
      case 4:
         return("Friday");
      default:
         return("Unknown");
     }
  }

#endif // TIME_BUCKET_ANALYZER_MQH
//+------------------------------------------------------------------+