Second(s) timeframes on your MT4

ALkhalil78

Trader
Jan 5, 2026
13
3
9
48
this script converts the chart's ticks into any Second(s)timeframes !!!

the Script works only for XAUUSD, you can modify it to work with other pairs or other names of Gold pair.

Example custom periods:

S5
S10
S15
S20
S30
S45
S50

Once the Second(s) chart is generated, you can apply almost everything you normally use on regular charts:

✅ Templates ( .tpl )
✅ Indicators
✅ Expert Advisors
✅ Objects & drawings
✅ Trendlines
✅ Fibonacci tools
✅ Moving averages
✅ Oscillators
✅ Custom indicators
✅ Price action tools



Enjoy the Script !!

MQL4:
//+------------------------------------------------------------------+
//|                                             XAUUSD_Seconds.mq4   |
//|                        Custom Seconds Offline Chart Generator    |
//|                        For MT4 Build 600+                        |
//+------------------------------------------------------------------+
#property strict
#property show_inputs
 
input int   InpSecondsPeriod = 10;      // Seconds timeframe
input bool  InpAutoOpenChart = true;    // Auto open offline chart
input bool  InpShowComment   = true;    // Show status comment
 
int      ExtHandle      = -1;
long     OfflineChartID = 0;
int      OfflinePeriod  = 20000;
 
datetime CurrentBarTime = 0;
 
MqlRates Rate;
 
string OfflineFileName;
 
//+------------------------------------------------------------------+
//| Script start                                                     |
//+------------------------------------------------------------------+
void OnStart()
{
   if(Symbol() != "XAUUSD")
   {
      Alert("Attach this script to XAUUSD only.");
      return;
   }
 
   if(InpSecondsPeriod < 1)
   {
      Alert("Seconds period must be >= 1");
      return;
   }
 
   OfflinePeriod += InpSecondsPeriod;
 
   OfflineFileName = Symbol() + (string)OfflinePeriod + ".hst";
 
   ExtHandle = FileOpenHistory(
      OfflineFileName,
      FILE_BIN|FILE_WRITE|FILE_SHARE_WRITE|FILE_SHARE_READ
   );
 
   if(ExtHandle < 0)
   {
      Alert("Failed to create offline history file.");
      return;
   }
 
   WriteHistoryHeader();
 
   WaitForFirstTick();
 
   BuildInitialBar();
 
   if(InpAutoOpenChart)
   {
      OpenOfflineChart();
   }
 
   MainLoop();
}
 
//+------------------------------------------------------------------+
//| Wait for first market tick                                       |
//+------------------------------------------------------------------+
void WaitForFirstTick()
{
   while(!IsStopped())
   {
      if(RefreshRates())
      {
         if(TimeCurrent() > 0)
            break;
      }
 
      Sleep(100);
   }
}
 
//+------------------------------------------------------------------+
//| Build first candle                                               |
//+------------------------------------------------------------------+
void BuildInitialBar()
{
   datetime now = TimeCurrent();
 
   CurrentBarTime = NormalizeSecondTime(now);
 
   Rate.time         = CurrentBarTime;
   Rate.open         = Bid;
   Rate.high         = Bid;
   Rate.low          = Bid;
   Rate.close        = Bid;
   Rate.tick_volume  = 1;
   Rate.spread       = MarketInfo(Symbol(), MODE_SPREAD);
   Rate.real_volume  = 0;
 
   FileWriteStruct(ExtHandle, Rate);
   FileFlush(ExtHandle);
}
 
//+------------------------------------------------------------------+
//| Main processing loop                                             |
//+------------------------------------------------------------------+
void MainLoop()
{
   datetime last_refresh = 0;
 
   while(!IsStopped())
   {
      RefreshRates();
 
      datetime now = TimeCurrent();
 
      datetime normalized = NormalizeSecondTime(now);
 
      if(normalized > CurrentBarTime)
      {
         FinalizeCurrentBar();
 
         StartNewBar(normalized);
      }
      else
      {
         UpdateCurrentBar();
      }
 
      if(InpShowComment)
      {
         Comment(
            "XAUUSD Seconds Chart Generator\n",
            "Seconds TF : S", InpSecondsPeriod, "\n",
            "Offline ID : ", OfflinePeriod, "\n",
            "Status     : RUNNING\n",
            "Bid        : ", DoubleToString(Bid, Digits)
         );
      }
 
      if(TimeLocal() - last_refresh >= 2)
      {
         RefreshOfflineChart();
         last_refresh = TimeLocal();
      }
 
      Sleep(20);
   }
 
   Comment("");
}
 
//+------------------------------------------------------------------+
//| Start new candle                                                 |
//+------------------------------------------------------------------+
void StartNewBar(datetime bar_time)
{
   CurrentBarTime = bar_time;
 
   Rate.time         = CurrentBarTime;
   Rate.open         = Bid;
   Rate.high         = Bid;
   Rate.low          = Bid;
   Rate.close        = Bid;
   Rate.tick_volume  = 1;
   Rate.spread       = MarketInfo(Symbol(), MODE_SPREAD);
   Rate.real_volume  = 0;
 
   FileWriteStruct(ExtHandle, Rate);
   FileFlush(ExtHandle);
}
 
//+------------------------------------------------------------------+
//| Update current candle                                            |
//+------------------------------------------------------------------+
void UpdateCurrentBar()
{
   if(Bid > Rate.high)
      Rate.high = Bid;
 
   if(Bid < Rate.low)
      Rate.low = Bid;
 
   Rate.close = Bid;
 
   Rate.tick_volume++;
 
   int struct_size = sizeof(MqlRates);
 
   FileSeek(ExtHandle, -struct_size, SEEK_END);
 
   FileWriteStruct(ExtHandle, Rate);
 
   FileFlush(ExtHandle);
}
 
//+------------------------------------------------------------------+
//| Finalize candle                                                  |
//+------------------------------------------------------------------+
void FinalizeCurrentBar()
{
   int struct_size = sizeof(MqlRates);
 
   FileSeek(ExtHandle, -struct_size, SEEK_END);
 
   FileWriteStruct(ExtHandle, Rate);
 
   FileFlush(ExtHandle);
}
 
//+------------------------------------------------------------------+
//| Normalize time                                                   |
//+------------------------------------------------------------------+
datetime NormalizeSecondTime(datetime t)
{
   return (t / InpSecondsPeriod) * InpSecondsPeriod;
}
 
//+------------------------------------------------------------------+
//| Write HST header                                                 |
//+------------------------------------------------------------------+
void WriteHistoryHeader()
{
   int    version = 401;
   string copyright;
   string symbol = Symbol();
   int    period = OfflinePeriod;
   int    digits = Digits;
   int    unused[13];
 
   ArrayInitialize(unused, 0);
 
   copyright = "Custom Seconds Chart";
 
   FileWriteInteger(ExtHandle, version, LONG_VALUE);
   FileWriteString(ExtHandle, copyright, 64);
   FileWriteString(ExtHandle, symbol, 12);
   FileWriteInteger(ExtHandle, period, LONG_VALUE);
   FileWriteInteger(ExtHandle, digits, LONG_VALUE);
   FileWriteInteger(ExtHandle, 0, LONG_VALUE);
   FileWriteInteger(ExtHandle, 0, LONG_VALUE);
 
   FileWriteArray(ExtHandle, unused, 0, 13);
}
 
//+------------------------------------------------------------------+
//| Open offline chart                                               |
//+------------------------------------------------------------------+
void OpenOfflineChart()
{
   OfflineChartID = ChartOpen(Symbol(), OfflinePeriod);
 
   Sleep(1000);
 
   RefreshOfflineChart();
}
 
//+------------------------------------------------------------------+
//| Refresh chart                                                    |
//+------------------------------------------------------------------+
void RefreshOfflineChart()
{
   if(OfflineChartID <= 0)
      return;
 
   ChartSetSymbolPeriod(
      OfflineChartID,
      Symbol(),
      OfflinePeriod
   );
 
   ChartRedraw(OfflineChartID);
}
 
//+------------------------------------------------------------------+
//| Cleanup                                                          |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Comment("");
 
   if(ExtHandle >= 0)
   {
      FileClose(ExtHandle);
      ExtHandle = -1;
   }
}
//+------------------------------------------------------------------+
 
Last edited by a moderator:
  • 👍
Reactions: Enivid
It looks like this script will just convert the real-time incoming ticks into a seconds chart. It doesn't convert any historical data, right?
Yes
Post automatically merged:

It looks like this script will just convert the real-time incoming ticks into a seconds chart. It doesn't convert any historical data, right?
run it once, forget it and let it go

you will have Second(s) charts the same as on OlympTrade site.
 
Sorry, how do I download and install this? I fully understand how to download and install indicator or EA files, but these appear to be lines of MQL programming code rather than a script file. Could you please post the script file?
 
Sorry, how do I download and install this? I fully understand how to download and install indicator or EA files, but these appear to be lines of MQL programming code rather than a script file. Could you please post the script file?
Select all the lines and then Ctrl+C and Ctrl+V it in a new blank file MetaEditor. Then save and compile.
 
Could you modify this source code so it works for all instruments? For instance, I currently trade Gold, but the symbol is XAUUSDz rather than XAUUSD (without the 'z' suffix), and I am unable to open a chart with a one-second timeframe. If possible, please create versions for both MT4 and MT5.
 
Could you modify this source code so it works for all instruments? For instance, I currently trade Gold, but the symbol is XAUUSDz rather than XAUUSD (without the 'z' suffix), and I am unable to open a chart with a one-second timeframe. If possible, please create versions for both MT4 and MT5.
Here's the modified script that can work with any symbol.
 

Attached File(s)

Thank you very much. My final request is: could you create a version for MT5? My friends and I recently switched to MT5 due to the many limitations of MT4, and I believe many traders today prefer MT5 over MT4. So, please—just this one last time—could you develop a full-instrument version for MT5?
 
Thank you very much. My final request is: could you create a version for MT5? My friends and I recently switched to MT5 due to the many limitations of MT4, and I believe many traders today prefer MT5 over MT4. So, please—just this one last time—could you develop a full-instrument version for MT5?
The MT5 version is available here:
 
MQL4:
//+------------------------------------------------------------------+
//|                                              Universal_Seconds.mq4|
//|                Universal Seconds Offline Chart Generator         |
//|                MT4 Build 600+                                    |
//+------------------------------------------------------------------+
#property strict
#property show_inputs
#property version   "2.00"
 
//+------------------------------------------------------------------+
//| Inputs                                                           |
//+------------------------------------------------------------------+
input int  InpSecondsPeriod = 10;       // Seconds timeframe
input bool InpAutoOpenChart = true;     // Auto open offline chart
input bool InpShowComment   = true;     // Show status comment
 
//+------------------------------------------------------------------+
//| Global variables                                                 |
//+------------------------------------------------------------------+
int      ExtHandle       = -1;
long     OfflineChartID  = 0;
int      OfflinePeriod   = 0;
 
datetime CurrentBarTime  = 0;
 
MqlRates Rate;
 
string   CurrentSymbol;
string   OfflineFileName;
 
//+------------------------------------------------------------------+
//| Script start                                                     |
//+------------------------------------------------------------------+
void OnStart()
{
   // Store the exact symbol to which the script is attached.
   // This automatically supports:
   // EURUSD
   // GBPUSD
   // XAUUSD
   // XAUUSDm
   // GOLD
   // BTCUSD
   // etc.
   CurrentSymbol = Symbol();
 
   // Validate seconds period.
   if(InpSecondsPeriod < 1)
   {
      Alert("Seconds period must be >= 1");
      return;
   }
 
   // Make sure the symbol has a valid market price.
   RefreshRates();
 
   double current_bid = MarketInfo(CurrentSymbol, MODE_BID);
 
   if(current_bid <= 0.0)
   {
      Alert(
         "No valid market price is available for ",
         CurrentSymbol,
         ". Make sure the symbol is active and receiving ticks."
      );
      return;
   }
 
   // ---------------------------------------------------------------
   // Create a unique offline timeframe.
   //
   // Example:
   // S10 -> 20010
   // S30 -> 20030
   // S60 -> 20060
   //
   // The symbol itself remains part of the HST filename.
   // ---------------------------------------------------------------
   OfflinePeriod = 20000 + InpSecondsPeriod;
 
   // Use the actual broker symbol.
   OfflineFileName = CurrentSymbol + (string)OfflinePeriod + ".hst";
 
   // ---------------------------------------------------------------
   // Open/create the offline history file.
   // FILE_WRITE creates a fresh file for this instance.
   // ---------------------------------------------------------------
   ExtHandle = FileOpenHistory(
      OfflineFileName,
      FILE_BIN |
      FILE_WRITE |
      FILE_SHARE_WRITE |
      FILE_SHARE_READ
   );
 
   if(ExtHandle < 0)
   {
      Alert(
         "Failed to create offline history file.\n",
         "Symbol: ", CurrentSymbol, "\n",
         "File: ", OfflineFileName, "\n",
         "Error: ", GetLastError()
      );
      return;
   }
 
   // Write standard MT4 HST header.
   WriteHistoryHeader();
 
   // Wait for the first market tick.
   WaitForFirstTick();
 
   if(IsStopped())
      return;
 
   // Build the first seconds candle.
   BuildInitialBar();
 
   // Open the offline chart if requested.
   if(InpAutoOpenChart)
      OpenOfflineChart();
 
   // Start processing ticks.
   MainLoop();
}
 
//+------------------------------------------------------------------+
//| Wait for first market tick                                       |
//+------------------------------------------------------------------+
void WaitForFirstTick()
{
   while(!IsStopped())
   {
      RefreshRates();
 
      double bid = MarketInfo(CurrentSymbol, MODE_BID);
 
      datetime server_time = TimeCurrent();
 
      if(server_time > 0 && bid > 0.0)
         break;
 
      Sleep(100);
   }
}
 
//+------------------------------------------------------------------+
//| Build first candle                                               |
//+------------------------------------------------------------------+
void BuildInitialBar()
{
   RefreshRates();
 
   double bid = MarketInfo(CurrentSymbol, MODE_BID);
 
   datetime now = TimeCurrent();
 
   CurrentBarTime = NormalizeSecondTime(now);
 
   ZeroMemory(Rate);
 
   Rate.time        = CurrentBarTime;
   Rate.open        = bid;
   Rate.high        = bid;
   Rate.low         = bid;
   Rate.close       = bid;
   Rate.tick_volume = 1;
   Rate.spread      = (long)MarketInfo(CurrentSymbol, MODE_SPREAD);
   Rate.real_volume = 0;
 
   FileWriteStruct(ExtHandle, Rate);
   FileFlush(ExtHandle);
}
 
//+------------------------------------------------------------------+
//| Main processing loop                                             |
//+------------------------------------------------------------------+
void MainLoop()
{
   datetime last_refresh = 0;
 
   while(!IsStopped())
   {
      // Update market data.
      RefreshRates();
 
      double bid = MarketInfo(CurrentSymbol, MODE_BID);
 
      // Some instruments can temporarily have no valid price.
      if(bid <= 0.0)
      {
         Sleep(20);
         continue;
      }
 
      datetime now = TimeCurrent();
 
      if(now <= 0)
      {
         Sleep(20);
         continue;
      }
 
      datetime normalized = NormalizeSecondTime(now);
 
      // ------------------------------------------------------------
      // A new seconds candle has started.
      // ------------------------------------------------------------
      if(normalized > CurrentBarTime)
      {
         FinalizeCurrentBar();
 
         StartNewBar(normalized);
      }
      else
      {
         // Same candle - update OHLC.
         UpdateCurrentBar();
      }
 
      // ------------------------------------------------------------
      // Display status.
      // ------------------------------------------------------------
      if(InpShowComment)
      {
         Comment(
            "Universal Seconds Chart Generator\n",
            "Symbol     : ", CurrentSymbol, "\n",
            "Seconds TF : S", InpSecondsPeriod, "\n",
            "Offline ID : ", OfflinePeriod, "\n",
            "Status     : RUNNING\n",
            "Bid        : ",
            DoubleToString(bid, (int)MarketInfo(CurrentSymbol, MODE_DIGITS))
         );
      }
 
      // ------------------------------------------------------------
      // Refresh offline chart periodically.
      // ------------------------------------------------------------
      if(TimeLocal() - last_refresh >= 2)
      {
         RefreshOfflineChart();
         last_refresh = TimeLocal();
      }
 
      Sleep(20);
   }
 
   Comment("");
}
 
//+------------------------------------------------------------------+
//| Start new candle                                                 |
//+------------------------------------------------------------------+
void StartNewBar(datetime bar_time)
{
   RefreshRates();
 
   double bid = MarketInfo(CurrentSymbol, MODE_BID);
 
   if(bid <= 0.0)
      return;
 
   CurrentBarTime = bar_time;
 
   ZeroMemory(Rate);
 
   Rate.time        = CurrentBarTime;
   Rate.open        = bid;
   Rate.high        = bid;
   Rate.low         = bid;
   Rate.close       = bid;
   Rate.tick_volume = 1;
   Rate.spread      = (long)MarketInfo(CurrentSymbol, MODE_SPREAD);
   Rate.real_volume = 0;
 
   FileWriteStruct(ExtHandle, Rate);
   FileFlush(ExtHandle);
}
 
//+------------------------------------------------------------------+
//| Update current candle                                            |
//+------------------------------------------------------------------+
void UpdateCurrentBar()
{
   RefreshRates();
 
   double bid = MarketInfo(CurrentSymbol, MODE_BID);
 
   if(bid <= 0.0)
      return;
 
   // Update high.
   if(bid > Rate.high)
      Rate.high = bid;
 
   // Update low.
   if(bid < Rate.low)
      Rate.low = bid;
 
   // Update close.
   Rate.close = bid;
 
   // Count ticks.
   Rate.tick_volume++;
 
   // Update current spread.
   Rate.spread = (long)MarketInfo(CurrentSymbol, MODE_SPREAD);
 
   // Rewrite the last HST record.
   int struct_size = sizeof(MqlRates);
 
   if(FileSeek(ExtHandle, -struct_size, SEEK_END))
   {
      FileWriteStruct(ExtHandle, Rate);
      FileFlush(ExtHandle);
   }
}
 
//+------------------------------------------------------------------+
//| Finalize current candle                                          |
//+------------------------------------------------------------------+
void FinalizeCurrentBar()
{
   int struct_size = sizeof(MqlRates);
 
   if(FileSeek(ExtHandle, -struct_size, SEEK_END))
   {
      FileWriteStruct(ExtHandle, Rate);
      FileFlush(ExtHandle);
   }
}
 
//+------------------------------------------------------------------+
//| Normalize time                                                   |
//+------------------------------------------------------------------+
datetime NormalizeSecondTime(datetime t)
{
   if(InpSecondsPeriod <= 1)
      return t;
 
   return (t / InpSecondsPeriod) * InpSecondsPeriod;
}
 
//+------------------------------------------------------------------+
//| Write HST header                                                 |
//+------------------------------------------------------------------+
void WriteHistoryHeader()
{
   int    version = 401;
   string copyright = "Universal Seconds Chart";
   string symbol = CurrentSymbol;
   int    period = OfflinePeriod;
   int    digits = (int)MarketInfo(CurrentSymbol, MODE_DIGITS);
   int    unused[13];
 
   ArrayInitialize(unused, 0);
 
   // HST header.
   FileWriteInteger(ExtHandle, version, LONG_VALUE);
 
   FileWriteString(
      ExtHandle,
      copyright,
      64
   );
 
   FileWriteString(
      ExtHandle,
      symbol,
      12
   );
 
   FileWriteInteger(
      ExtHandle,
      period,
      LONG_VALUE
   );
 
   FileWriteInteger(
      ExtHandle,
      digits,
      LONG_VALUE
   );
 
   FileWriteInteger(
      ExtHandle,
      0,
      LONG_VALUE
   );
 
   FileWriteInteger(
      ExtHandle,
      0,
      LONG_VALUE
   );
 
   FileWriteArray(
      ExtHandle,
      unused,
      0,
      13
   );
}
 
//+------------------------------------------------------------------+
//| Open offline chart                                               |
//+------------------------------------------------------------------+
void OpenOfflineChart()
{
   // Open the exact current symbol.
   OfflineChartID = ChartOpen(
      CurrentSymbol,
      OfflinePeriod
   );
 
   if(OfflineChartID <= 0)
   {
      Print(
         "Unable to open offline chart. ",
         "Symbol=", CurrentSymbol,
         " Period=", OfflinePeriod,
         " Error=", GetLastError()
      );
 
      return;
   }
 
   Sleep(1000);
 
   RefreshOfflineChart();
}
 
//+------------------------------------------------------------------+
//| Refresh offline chart                                            |
//+------------------------------------------------------------------+
void RefreshOfflineChart()
{
   if(OfflineChartID <= 0)
      return;
 
   // Make sure the chart belongs to the correct symbol/timeframe.
   ChartSetSymbolPeriod(
      OfflineChartID,
      CurrentSymbol,
      OfflinePeriod
   );
 
   ChartRedraw(OfflineChartID);
}
 
//+------------------------------------------------------------------+
//| Cleanup                                                          |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
   Comment("");
 
   // Close history file.
   if(ExtHandle >= 0)
   {
      FileFlush(ExtHandle);
      FileClose(ExtHandle);
      ExtHandle = -1;
   }
 
   // We intentionally do NOT close the offline chart here.
   // The user may want to keep the chart open after stopping
   // the generator.
   OfflineChartID = 0;
}
//+------------------------------------------------------------------+
 
Last edited by a moderator: