//+------------------------------------------------------------------+
//|                                                    CacheDemo.mq5 |
//+------------------------------------------------------------------+

#include <SymbolMetaCache\SymbolMeta.mqh>
#include <SymbolMetaCache\SymbolMetaCache.mqh>

//--- Inputs
input string InpSymbol1 = "EURUSD";   // Symbol 1
input string InpSymbol2 = "GBPUSD";   // Symbol 2
input string InpSymbol3 = "USDJPY";   // Symbol 3
input string InpSymbol4 = "AUDUSD";   // Symbol 4
input string InpSymbol5 = "USDCAD";   // Symbol 5

CSymbolMetaCache g_cache;
int              g_last_logged_hour;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
   string symbols[5];
   symbols[0] = InpSymbol1;
   symbols[1] = InpSymbol2;
   symbols[2] = InpSymbol3;
   symbols[3] = InpSymbol4;
   symbols[4] = InpSymbol5;

   if(!g_cache.Init(symbols, 5))
      Print("CacheDemo: OnInit - one or more symbols failed to initialize in the cache.");

   g_cache.PrintAll();

//--- fire once per hour; OnTimer checks for midnight boundary
   EventSetTimer(3600);
   g_last_logged_hour = -1;

   return(INIT_SUCCEEDED);
  }

//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   MqlDateTime mdt;
   TimeToStruct(TimeTradeServer(), mdt);

//--- log once per hour to avoid flooding the Experts tab
   if(mdt.hour == g_last_logged_hour)
      return;

   g_last_logged_hour = mdt.hour;

   double point      = g_cache.GetPoint(_Symbol);
   double tick_value  = g_cache.GetTickValue(_Symbol);
   double lot_step    = g_cache.GetLotStep(_Symbol);
   bool   market_open = g_cache.IsMarketOpen(_Symbol, TimeTradeServer());

   PrintFormat("CacheDemo: %s  point=%.5f  tick_value=%.5f  lot_step=%.2f  market_open=%s",
               _Symbol, point, tick_value, lot_step,
               (market_open ? "true" : "false"));
  }

//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   MqlDateTime mdt;
   TimeToStruct(TimeTradeServer(), mdt);

//--- refresh only at the midnight hour boundary
   if(mdt.hour != 0)
      return;

   datetime before = g_cache.GetLastRefreshTime();
   g_cache.Refresh();
   datetime after = g_cache.GetLastRefreshTime();

   PrintFormat("CacheDemo: OnTimer - daily refresh triggered.  before=%s  after=%s",
               TimeToString(before, TIME_DATE | TIME_SECONDS),
               TimeToString(after,  TIME_DATE | TIME_SECONDS));
  }

//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
   EventKillTimer();
   PrintFormat("CacheDemo: OnDeinit - shutting down.  last_refresh=%s",
               TimeToString(g_cache.GetLastRefreshTime(), TIME_DATE | TIME_SECONDS));
  }
//+------------------------------------------------------------------+