2026-11-04 00:44:06 +01:00 | | | //+------------------------------------------------------------------+
|
| | | //| 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).|
|
| | | //| |
|
2026-11-04 15:03:18 +01:00 | | | //| 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. |
|
2026-11-04 00:44:06 +01:00 | | | //+------------------------------------------------------------------+
|
| | | #property copyright "Copyright (c) 2026 Joshua Dunnink - MIT License"
|
| | | #property link "https://forge.mql5.io/joshuadunnink/Tick_Forge"
|
2026-11-04 15:50:31 +01:00 | | | #property version "1.04"
|
2026-11-04 07:30:30 +01:00 | | | #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."
|
2026-11-04 00:44:06 +01:00 | | | #property strict
|
| | |
|
2026-11-04 15:03:18 +01:00 | | | #include "TF_Gui.mqh"
|
2026-11-04 00:44:06 +01:00 | | |
|
2026-11-04 01:33:38 +01:00 | | | int OnInit()
|
2026-11-04 00:44:06 +01:00 | | | {
|
2026-11-04 15:50:31 +01:00 | | | PrintFormat("Tick Forge v1.04 | chart %s", _Symbol);
|
2026-11-04 07:30:30 +01:00 | | | 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;
|
| | | }
|
2026-11-04 00:44:06 +01:00 | | | g_dlg = new CTickForgeDlg();
|
2026-11-04 15:50:31 +01:00 | | | if(!g_dlg.Create(0, "Tick Forge 1.04", 0, 20, 20, 20 + TF_W, 20 + TF_H))
|
2026-11-04 01:33:38 +01:00 | | | {
|
2026-11-04 07:30:30 +01:00 | | | 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);
|
2026-11-04 01:33:38 +01:00 | | | delete g_dlg; g_dlg = NULL;
|
2026-11-04 07:30:30 +01:00 | | | return INIT_SUCCEEDED;
|
2026-11-04 01:33:38 +01:00 | | | }
|
2026-11-04 00:44:06 +01:00 | | | g_dlg.Run();
|
2026-11-04 15:03:18 +01:00 | | | EventSetMillisecondTimer(30);
|
2026-11-04 01:33:38 +01:00 | | | return INIT_SUCCEEDED;
|
2026-11-04 00:44:06 +01:00 | | | }
|
| | |
|
2026-11-04 01:33:38 +01:00 | | | void OnDeinit(const int reason)
|
| | | {
|
2026-11-04 15:03:18 +01:00 | | | EventKillTimer();
|
2026-11-04 01:33:38 +01:00 | | | if(g_dlg != NULL) { g_dlg.Destroy(reason); delete g_dlg; g_dlg = NULL; }
|
2026-11-04 07:30:30 +01:00 | | | Comment("");
|
2026-11-04 01:33:38 +01:00 | | | }
|
| | |
|
| | | void OnTick() {}
|
| | |
|
2026-11-04 15:03:18 +01:00 | | | 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();
|
| | | }
|
| | |
|
2026-11-04 00:44:06 +01:00 | | | 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);
|
| | | }
|
| | | //+------------------------------------------------------------------+
|