//+------------------------------------------------------------------+
//|                                          DealSampleExtractor.mqh |
//+------------------------------------------------------------------+
#ifndef DEALSAMPLEEXTRACTOR_MQH
#define DEALSAMPLEEXTRACTOR_MQH

#include "HeatmapTypes.mqh"

//+------------------------------------------------------------------+
//| CDealSampleExtractor                                             |
//| Reads closed deal history for a date range and reduces each deal |
//| to its symbol, close hour, and net profit. The hour is taken     |
//| directly from the deal's own close-time timestamp and treated as |
//| UTC without conversion or verification; see the Limitations      |
//| section for what this assumes about the broker's reported time.  |
//+------------------------------------------------------------------+
class CDealSampleExtractor
class CDealSampleExtractor
  {
public:
                     CDealSampleExtractor(void);
                    ~CDealSampleExtractor(void);

   int                   Read(datetime from, datetime to, CDealSample &deals_out[]);
  };

//+------------------------------------------------------------------+
//| Constructor: no member state to initialize.                      |
//+------------------------------------------------------------------+
CDealSampleExtractor::CDealSampleExtractor(void)
  {
  }

//+------------------------------------------------------------------+
//| Destructor: no dynamic resources to release.                     |
//+------------------------------------------------------------------+
CDealSampleExtractor::~CDealSampleExtractor(void)
  {
  }

//+------------------------------------------------------------------+
//| Read                                                             |
//| Selects history for the given date range, keeps only closing     |
//| deals, and records each one's symbol, close hour, and net profit |
//| (profit + swap + commission). The close hour is read straight    |
//| from the deal's own timestamp with no time zone conversion, so   |
//| it is only as accurate as the assumption that the broker already |
//| reports deal times in UTC. Returns the number of samples         |
//| populated.                                                       |
//+------------------------------------------------------------------+
int CDealSampleExtractor::Read(datetime from, datetime to, CDealSample &deals_out[])
int CDealSampleExtractor::Read(datetime from, datetime to, CDealSample &deals_out[])
  {
//--- scope the terminal's history cache to the requested range
   if(!::HistorySelect(from, to))
     {
      ::Print("HeatmapDashboard: HistorySelect failed, error ", ::GetLastError());
      return(0);
     }
   int      total      = ::HistoryDealsTotal();
   ::ArrayResize(deals_out, total);
   int      found      = 0;
   ulong    ticket     = 0;
   long     entry_type = 0;
   double   profit     = 0.0;
   double   swap       = 0.0;
   double   commission = 0.0;
   string   symbol     = "";
   datetime close_time = 0;
   MqlDateTime dt;
//--- iterate every deal in the selected history range
   for(int i = 0; i < total; i++)
     {
      ticket = ::HistoryDealGetTicket(i);
      if(ticket == 0)
         continue;
      //--- keep only deals that represent an actual closed trade
      entry_type = ::HistoryDealGetInteger(ticket, DEAL_ENTRY);
      if(entry_type != DEAL_ENTRY_OUT && entry_type != DEAL_ENTRY_INOUT)
         continue;
      profit     = ::HistoryDealGetDouble(ticket, DEAL_PROFIT);
      swap       = ::HistoryDealGetDouble(ticket, DEAL_SWAP);
      commission = ::HistoryDealGetDouble(ticket, DEAL_COMMISSION);
      symbol     = ::HistoryDealGetString(ticket, DEAL_SYMBOL);
      close_time = (datetime)::HistoryDealGetInteger(ticket, DEAL_TIME);
      //--- extract the hour component from the close time, assumed to
      //--- already be UTC; no conversion is performed here
      ::TimeToStruct(close_time, dt);
      deals_out[found].symbol   = symbol;
      deals_out[found].hour_utc = dt.hour;
      deals_out[found].profit   = profit + swap + commission;
      found++;
     }
   ::ArrayResize(deals_out, found);
   return(found);
  }

#endif // DEALSAMPLEEXTRACTOR_MQH
//+------------------------------------------------------------------+