Tick_Forge/Tick_Forge.mq5
//+------------------------------------------------------------------+
//| Tick_Forge.mq5 |
//| 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: attach it to any chart to open its window. It 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 never trades. Free and open source (MIT). No DLL, no internet access."
#property strict
#include "TF_Gui.mqh"
int OnInit()
{
PrintFormat("Tick Forge v1.04 | chart %s", _Symbol);
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("");
}
void OnTick() {}
void OnTimer()
{
if(g_dlg == NULL) return;
g_dlg.Tick(); // one day / one month of work per call, so the window stays responsive
if(g_dlg.Closed()) ExpertRemove();
}
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);
}
//+------------------------------------------------------------------+