//+------------------------------------------------------------------+ //| Tick_Forge_Indicator.mq5 (alternate build) | //| Copyright (c) 2026 Joshua Dunnink. MIT License (see LICENSE). | //| | //| Build custom backtesting symbols from your broker's own history: | //| - shift the raw timestamps by hours or days | //| - rescale / reshape prices with a typed function | //| - write real (transformed) ticks or M1 bars | //| The result is an ordinary custom symbol the Strategy Tester can | //| use (Every tick / Every tick based on real ticks / 1 minute OHLC).| //| | //| A utility indicator: it draws nothing and never trades. The | //| source is open and it uses no DLL. It writes only the custom | //| symbol (its bars and ticks) - nothing else. | //+------------------------------------------------------------------+ #property copyright "Copyright (c) 2026 Joshua Dunnink - MIT License" #property link "https://forge.mql5.io/joshuadunnink/Tick_Forge" #property version "1.04" #property description "Tick Forge builds custom symbols for the Strategy Tester from your broker's own history." #property description "Shift the timestamps, rescale or reshape the prices with a typed function, test your EA on the result." #property description "Utility: it draws nothing and never trades. Free and open source (MIT). No DLL, no internet access." #property indicator_chart_window #property indicator_plots 0 #include "TF_Gui.mqh" int OnInit() { PrintFormat("Tick Forge v1.04 | chart %s", _Symbol); IndicatorSetString(INDICATOR_SHORTNAME, "Tick Forge"); if(MQLInfoInteger(MQL_TESTER) || MQLInfoInteger(MQL_OPTIMIZATION)) { Print("Tick Forge is a utility for a live chart (it creates symbols); it does nothing in the Strategy Tester."); return INIT_SUCCEEDED; } g_dlg = new CTickForgeDlg(); if(!g_dlg.Create(0, "Tick Forge 1.04", 0, 20, 20, 20 + TF_W, 20 + TF_H)) { const string need = StringFormat("Tick Forge needs a chart of at least %d x %d pixels (enlarge the window or maximise the chart).", TF_W + 40, TF_H + 40); Print(need); Comment(need); delete g_dlg; g_dlg = NULL; return INIT_SUCCEEDED; } g_dlg.Run(); EventSetMillisecondTimer(30); return INIT_SUCCEEDED; } void OnDeinit(const int reason) { EventKillTimer(); if(g_dlg != NULL) { g_dlg.Destroy(reason); delete g_dlg; g_dlg = NULL; } Comment(""); } int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) { return rates_total; } void OnTimer() { if(g_dlg == NULL) return; g_dlg.Tick(); if(g_dlg.Closed()) { EventKillTimer(); ChartIndicatorDelete(0, 0, "Tick Forge"); } } void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(g_dlg != NULL) g_dlg.ChartEvent(id, lparam, dparam, sparam); } //+------------------------------------------------------------------+