//+------------------------------------------------------------------+
//|                                            DealSampleReader.mqh  |
//+------------------------------------------------------------------+
#ifndef DEALSAMPLEREADER_MQH
#define DEALSAMPLEREADER_MQH

#include "CalendarTypes.mqh"

//+------------------------------------------------------------------+
//| CDealSampleReader                                                |
//| Reads closed deal history for a requested time range and reduces |
//| each relevant deal to a CDealSample. Only deal entries that      |
//| realize profit or loss are included: DEAL_ENTRY_OUT (a position  |
//| closed by an opposite deal) and DEAL_ENTRY_INOUT (a position     |
//| closed and reversed by the same deal). DEAL_ENTRY_IN deals, which|
//| open a position, are intentionally excluded because a position's |
//| profit is not realized at the moment it is opened; including     |
//| entry deals would double count activity without contributing any |
//| additional realized P&L.                                         |
//+------------------------------------------------------------------+
class CDealSampleReader
  {
public:
                     CDealSampleReader(void);
                    ~CDealSampleReader(void);
   bool              Read(datetime from, datetime to, CDealSample &deals_out[]);
  };

//+------------------------------------------------------------------+
//| Constructor                                                      |
//| The reader is stateless between calls, so construction performs  |
//| no work beyond default object creation.                          |
//+------------------------------------------------------------------+
CDealSampleReader::CDealSampleReader(void)
  {
  }

//+------------------------------------------------------------------+
//| Destructor                                                       |
//| No resources are owned by this class, so no cleanup is required. |
//+------------------------------------------------------------------+
CDealSampleReader::~CDealSampleReader(void)
  {
  }

//+------------------------------------------------------------------+
//| Read                                                             |
//| Selects the terminal's history cache for [from, to] and copies   |
//| every closing-related deal into deals_out, reduced to close time |
//| and net profit. Net profit is defined as the deal's own profit   |
//| field plus its swap and commission contributions, which is a     |
//| deliberate and documented design choice: it reflects what the    |
//| account actually realized because of that deal, not merely the   |
//| raw trading result before costs. Callers should be aware that    |
//| history availability depends on the terminal's local history     |
//| cache and on how far back the connected account retains records; |
//| a range that predates the available history simply yields fewer  |
//| samples rather than an error.                                    |
//+------------------------------------------------------------------+
bool CDealSampleReader::Read(datetime from,datetime to,CDealSample &deals_out[])
  {
//--- start from an empty output buffer regardless of any prior contents
   ::ArrayResize(deals_out, 0);
//--- ask the terminal to build the history cache for the requested interval
   if(!::HistorySelect(from, to))
     {
      ::Print("CDealSampleReader: HistorySelect failed for the requested range.");
      return(false);
     }
//--- walk every deal available in the freshly selected history cache
   int total_deals = ::HistoryDealsTotal();
   for(int i = 0; i < total_deals; i++)
     {
      ulong ticket = ::HistoryDealGetTicket(i);
      if(ticket == 0)
         continue;
      //--- only closing-related deal entries realize profit or loss
      long entry_type = ::HistoryDealGetInteger(ticket, DEAL_ENTRY);
      if(entry_type != DEAL_ENTRY_OUT && entry_type != DEAL_ENTRY_INOUT)
         continue;
      //--- reduce the deal to its close time and its net profit contribution
      double net_profit  = ::HistoryDealGetDouble(ticket, DEAL_PROFIT)
                           + ::HistoryDealGetDouble(ticket, DEAL_SWAP)
                           + ::HistoryDealGetDouble(ticket, DEAL_COMMISSION);
      datetime close_time = (datetime)::HistoryDealGetInteger(ticket, DEAL_TIME);
      //--- append the reduced sample to the output array
      int new_index = ::ArraySize(deals_out);
      ::ArrayResize(deals_out, new_index + 1);
      deals_out[new_index].m_close_time = close_time;
      deals_out[new_index].m_net_profit = net_profit;
     }
   return(true);
  }

#endif // DEALSAMPLEREADER_MQH
//+------------------------------------------------------------------+