//+------------------------------------------------------------------+
//|                                              GoldSecondsMT5.mq5  |
//|                     MT5 Native Seconds Chart Generator            |
//|                     Custom Symbol Engine Version                  |
//+------------------------------------------------------------------+
#property strict

input string InpSourceSymbol = "XAUUSD";
input int    InpSeconds      = 10;
input bool   InpAutoOpen     = true;

string CustomSymbolName;

MqlRates CurrentBar;

datetime CurrentBarTime = 0;

long LastTickTimeMSC = 0;

//+------------------------------------------------------------------+
//| Expert initialization                                            |
//+------------------------------------------------------------------+
int OnInit()
{
   if(InpSeconds < 1)
   {
      Print("Seconds must be >= 1");
      return(INIT_FAILED);
   }

   CustomSymbolName = InpSourceSymbol + "_S" + IntegerToString(InpSeconds);

   Print("Creating custom symbol: ", CustomSymbolName);

   CreateCustomSymbol();

   OpenCustomChart();

   EventSetMillisecondTimer(50);

   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert deinitialization                                          |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   EventKillTimer();
}

//+------------------------------------------------------------------+
//| Millisecond timer                                                |
//+------------------------------------------------------------------+
void OnTimer()
{
   MqlTick tick;

   if(!SymbolInfoTick(InpSourceSymbol, tick))
      return;

   if(tick.time_msc == LastTickTimeMSC)
      return;

   LastTickTimeMSC = tick.time_msc;

   ProcessTick(tick);
}

//+------------------------------------------------------------------+
//| Process incoming tick                                            |
//+------------------------------------------------------------------+
void ProcessTick(MqlTick &tick)
{
   datetime bar_time =
      (datetime)((tick.time / InpSeconds) * InpSeconds);

   //--- First bar
   if(CurrentBarTime == 0)
   {
      StartNewBar(bar_time, tick);
      return;
   }

   //--- New candle
   if(bar_time > CurrentBarTime)
   {
      PushBarToCustomSymbol(CurrentBar);

      StartNewBar(bar_time, tick);
   }
   else
   {
      UpdateCurrentBar(tick);
   }
}

//+------------------------------------------------------------------+
//| Start new candle                                                 |
//+------------------------------------------------------------------+
void StartNewBar(datetime bar_time, MqlTick &tick)
{
   CurrentBarTime = bar_time;

   CurrentBar.time        = bar_time;
   CurrentBar.open        = tick.bid;
   CurrentBar.high        = tick.bid;
   CurrentBar.low         = tick.bid;
   CurrentBar.close       = tick.bid;
   CurrentBar.tick_volume = 1;
   CurrentBar.spread      = 0;
   CurrentBar.real_volume = 0;
}

//+------------------------------------------------------------------+
//| Update current candle                                            |
//+------------------------------------------------------------------+
void UpdateCurrentBar(MqlTick &tick)
{
   if(tick.bid > CurrentBar.high)
      CurrentBar.high = tick.bid;

   if(tick.bid < CurrentBar.low)
      CurrentBar.low = tick.bid;

   CurrentBar.close = tick.bid;

   CurrentBar.tick_volume++;
}

//+------------------------------------------------------------------+
//| Push candle to custom symbol                                     |
//+------------------------------------------------------------------+
void PushBarToCustomSymbol(MqlRates &bar)
{
   MqlRates rates[1];

   rates[0] = bar;

   if(!CustomRatesUpdate(CustomSymbolName, rates))
   {
      Print("CustomRatesUpdate failed. Error: ", GetLastError());
   }
}

//+------------------------------------------------------------------+
//| Create custom symbol                                             |
//+------------------------------------------------------------------+
void CreateCustomSymbol()
{
   //--- already exists
   if(SymbolSelect(CustomSymbolName, true))
   {
      Print("Custom symbol already exists.");
      return;
   }

   //--- create
   if(!CustomSymbolCreate(
      CustomSymbolName,
      "Custom",
      InpSourceSymbol))
   {
      Print("Failed creating custom symbol. Error: ", GetLastError());
      return;
   }

   //--- select
   SymbolSelect(CustomSymbolName, true);

   //--- synchronize properties
   CustomSymbolSetInteger(
      CustomSymbolName,
      SYMBOL_DIGITS,
      (int)SymbolInfoInteger(InpSourceSymbol, SYMBOL_DIGITS)
   );

   CustomSymbolSetDouble(
      CustomSymbolName,
      SYMBOL_POINT,
      SymbolInfoDouble(InpSourceSymbol, SYMBOL_POINT)
   );

   Print("Custom symbol created successfully.");
}

//+------------------------------------------------------------------+
//| Open custom chart                                                |
//+------------------------------------------------------------------+
void OpenCustomChart()
{
   if(!InpAutoOpen)
      return;

   long chart_id = ChartOpen(CustomSymbolName, PERIOD_M1);

   if(chart_id > 0)
   {
      Print("Custom chart opened.");
   }
   else
   {
      Print("Failed opening chart.");
   }
}
//+------------------------------------------------------------------+