//+------------------------------------------------------------------+
//|                                                  MarketCache.mqh |
//|                                Copyright 2026, Clemence Benjamin |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, Clemence Benjamin"
#property link      "https://www.mql5.com"

#include "../Common/Structures.mqh"
#include "../Common/Globals.mqh"

//+------------------------------------------------------------------+
//| Class: CMarketDataCache                                          |
//| Purpose: Caches market data to avoid redundant API calls         |
//+------------------------------------------------------------------+
class CMarketDataCache
  {
private:
   MarketSnapshot    m_data[];       // cached market data
   bool              m_isValid;      // cache validity flag
   datetime          m_lastRefresh;  // last refresh timestamp

public:
   //+------------------------------------------------------------------+
   //| Constructor                                                      |
   //+------------------------------------------------------------------+
                     CMarketDataCache() : m_isValid(false), m_lastRefresh(0) {}

   //+------------------------------------------------------------------+
   //| Refreshes market data from the terminal                          |
   //+------------------------------------------------------------------+
   bool              Refresh()
     {
      datetime now = TimeCurrent();
      if(now - m_lastRefresh < 1)
         return(m_isValid);
      MqlRates rates[];
      ArraySetAsSeries(rates, true);
      if(CopyRates(_Symbol, _Period, 0, 3, rates) < 3)
         return(false);
      //--- Store data in the structure
      ArrayResize(m_data, 1);
      m_data[0].time   = rates[0].time;
      m_data[0].open   = rates[0].open;
      m_data[0].high   = rates[0].high;
      m_data[0].low    = rates[0].low;
      m_data[0].close  = rates[0].close;
      m_data[0].bid    = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      m_data[0].ask    = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      m_data[0].spread = (m_data[0].ask - m_data[0].bid) / g_point;
      m_isValid = true;
      m_lastRefresh = now;
      return(true);
     }

   //+------------------------------------------------------------------+
   //| Accessor methods                                                 |
   //+------------------------------------------------------------------+
   double            GetBid() const      { return(m_isValid ? m_data[0].bid : 0); }
   double            GetAsk() const      { return(m_isValid ? m_data[0].ask : 0); }
   double            GetClose() const    { return(m_isValid ? m_data[0].close : 0); }
   datetime          GetTime() const     { return(m_isValid ? m_data[0].time : 0); }
   double            GetSpread() const   { return(m_isValid ? m_data[0].spread : 0); }
  };
//+------------------------------------------------------------------+

