In April 2025 I built what I was sure was the perfect indicator. "WolfSignal" combined RSI momentum, a MACD cross, and an ATR volatility gate into clean green and red arrows on the chart. I scrolled back through two years of EURUSD history and counted: 78% of the arrows would have been winners. I put it live on a $3,500 account, took every arrow for six weeks, and watched it go 41% on wins. Final damage: −$680. Same indicator. Same arrows. Half the win rate.
The arrows were lying. My indicator repainted — it recalculated past signals using data that did not exist when the bar was live. On historical charts every arrow sat at the perfect spot because the code peeked at the future to draw the past. Live, the arrows appeared, disappeared, and jumped between bars like nervous fireflies. That six-week tuition bill taught me the real syllabus of mt5 indicators custom tools development: the math is the easy part, honesty is the hard part.
I rebuilt WolfSignal from zero with closed-bar-only logic, benchmarked every build before it touched a live chart, and paired it with the DarkWolf MT5 Signal Calculator so each arrow gets sized like a real trade instead of a decoration. The honest version wins 54% — less photogenic, actually profitable. Here is everything the repainting disaster taught me about building custom tools for MT5.
The indicator bugs that taught me to test everything twice
Bug one was the repainting itself, and it deserves a precise explanation because it is the most expensive bug in indicator development. My code read the forming bar's close to confirm signals. On a historical chart, the "forming" bar of 2023 is long closed, so the arrows looked perfect. Live, the bar was still moving, so the signal flickered in and out until the bar closed — usually resolving against me. The fix: never evaluate a signal on bar zero. Signals confirm only on closed bars. My win rate dropped from a fictional 78% to an honest 54% overnight, and I have never trusted a historical arrow since.
Bug two: future-leak through indicator handles. I called a moving average with a shift parameter that reached into bars that had not formed yet at signal time — subtler repainting, same poison. Bug three was performance: my indicator recalculated its entire 5,000-bar history on every tick. The terminal froze for two seconds per tick during London open. I learned to compute incrementally — only new bars, cache the rest. Bug four: alert spam. My first alert logic fired on every tick while conditions held, sending 340 push notifications in one afternoon. My phone nearly melted. Alerts now fire once per signal, keyed to the bar's timestamp.
The meta-lesson: backtest your indicator, not just your strategy. I now run every custom tool through a replay test — step through history bar by bar in the visual tester and confirm signals appear exactly once, never move, and never vanish. The set-file optimization guide covers the same discipline for EA parameters: optimize the tool, then distrust the optimization until forward data confirms it.
The math inside the indicators I actually use
After the repainting fiasco I stripped WolfSignal down to math I could defend line by line. The core is a z-score: how far price has stretched from its moving average, measured in standard deviations. It is simple, it does not peek at the future when coded on closed bars, and it tells you something real — whether the current move is ordinary or extreme.
| Variable | Meaning | Example value |
|---|---|---|
| Close | Close of the last fully closed bar — never the forming bar | 1.0872 (EURUSD H1) |
| MA20 | 20-period simple moving average of closed bars | 1.0841 |
| StdDev20 | Standard deviation of closes over the same 20 bars | 0.0014 (14 pips) |
| Z-Score | Stretch in standard deviations; ±2.0 ≈ the outer 5% of moves | +2.2 → extension signal |
Worked: (1.0872 − 1.0841) ÷ 0.0014 = +2.2. Price sits 2.2 standard deviations above its average — stretched, and my indicator flags a mean-reversion setup only after that bar closes. The RSI and MACD layers add confirmation, but the z-score is the skeleton. Investopedia's statistics reference is where I sanity-checked the standard-deviation interpretation before trusting it with money — a non-trading source keeping my trading math honest.
Shipping a custom tool without breaking my trading routine
Building the indicator is half the job. Deploying it without destabilizing everything else is the other half. My rollout protocol now: version every build (WolfSignal v1.0, v1.1 — never "final_final"), run it on one chart for two weeks before adding it to others, and keep a changelog of what changed and why. When v1.3 started behaving oddly in August, the changelog told me in ten seconds that the ATR gate was the only change — diagnosis done before coffee.
Performance budgeting matters more than beginners expect. Each custom indicator adds CPU load on every tick, and five heavy indicators on eight charts can make MT5 stutter exactly when you need it responsive. I benchmark every build: attach it to a chart, watch the terminal's CPU in Task Manager during a busy session, and reject anything that pushes sustained usage up noticeably. My z-score indicator uses under 1% — the original repainting version with full-history recalculation used 14%. Same signals, fourteen times the cost.
Alert discipline is the last piece. A custom tool should notify, not nag. My rules: one alert per signal, alerts only during my trading sessions, and a daily cap — if an indicator fires more than 10 signals a day, the threshold is too loose and I retune instead of tolerating noise. A tool that cries wolf gets ignored, and an ignored tool is worse than no tool. The scalping mode performance notes show how signal frequency interacts with session quality — relevant because most custom indicators over-fire in dead sessions.
Setting up the calculator alongside a custom indicator
An arrow without a position size is a suggestion, not a trade. Every WolfSignal arrow goes through the calculator before I act — the indicator answers when, the calculator answers how much. The ATR reading at signal time sets the stop distance, which sets the size. No fixed lots, ever.
| Input Field | What it means | Sample value |
|---|---|---|
| Account balance | Live equity when the arrow fires | $3,500 |
| Risk % | Per-signal risk; I use 0.75% for indicator signals | 0.75% |
| Indicator signal | The trigger: z-score beyond ±2.0 on a closed bar | Z = +2.2, short setup |
| ATR at signal | Current volatility reading from the indicator | 22 pips (H1) |
| Stop distance | Set as 1.5 × ATR so the stop breathes with volatility | 33 pips |
| Session filter | Signals outside liquid sessions get skipped | London + New York only |
How MT5 custom indicators really work under the hood
The architecture surprised me when I learned it properly. A custom indicator in MT5 is a program that computes and draws — it cannot trade. No order functions, no position management. That limitation is actually a safety feature: the worst a buggy indicator can do is draw nonsense, not open positions. (EAs are the ones that can hurt you; indicators can only mislead you, which as I learned is bad enough.)
The engine room is the OnCalculate function. MT5 calls it whenever new data arrives, passing the full price arrays and telling your code which bars are new via the prev_calculated counter. Your job: compute values only for the new bars, store them in indicator buffers, and let MT5 render those buffers as lines, arrows, or histogram bars. The buffer system is the whole drawing model — an arrow on your chart is just a buffer value at a bar index with a drawing style attached.
Three under-the-hood facts that changed how I code. First, prev_calculated is your performance lifeline: ignore it and you recompute history every tick (my 14% CPU bug). Second, indicator buffers have fixed semantics — you declare them up front, and MT5 handles the rendering, which means custom drawing is declarative, not procedural. Third, an indicator's values are readable by EAs through iCustom, which is how WolfSignal graduated from chart decoration to actual strategy input: my EA reads the z-score buffer and trades it with the calculator's sizing. The market structure overlay is a good example of this done well — clean buffers, closed-bar logic, readable by automation.
Indicator builds I benchmarked before putting them on charts
Four builds of WolfSignal, each one earning its place. The table is the development diary I wish someone had shown me before I started — notice how the "improvements" kept making the backtest prettier while the honesty checks made it tradable.
| Build | What it computed | Honesty & performance test | Verdict |
|---|---|---|---|
| v1.0 | RSI + MACD + ATR arrows, forming-bar logic | Replay test: arrows moved and vanished — repainting confirmed | Scrapped after the −$680 lesson |
| v1.1 | Same signals, closed-bar-only evaluation | Replay: arrows stable, never move; win rate honest 54% | First trustworthy build |
| v1.2 | Added z-score core, dropped MACD | Forward demo 6 weeks: 56% wins, CPU under 1% | Simpler and better — kept |
| v1.3 | Added session filter + one-alert-per-bar | Alert count dropped 70%, win rate steady at 55% | Current live build |
The through-line: every build that made the historical chart prettier made live trading worse, and every build that made the code more honest made live trading better. Optimize for the replay test, not the screenshot. The FCA's consumer warnings about trading software overpromising returns say the same thing in regulatory language — if a tool's marketing shows perfect historical signals, assume repainting until proven otherwise.
Custom indicator questions I get every week
What is repainting and how do I detect it?
Repainting is when an indicator redraws past signals using data that was not available at the time — usually by evaluating the still-forming bar. Detect it with a replay test: step through history bar by bar in the visual tester and watch whether signals appear, move, or vanish. Stable arrows that never relocate are honest. Any signal that jumps between bars is lying to you, no matter how good the historical chart looks.
Can a custom indicator place trades by itself?
No — and this is by design. MT5 indicators can compute and draw but cannot call trade functions. If you want automation, build an EA that reads your indicator's buffers via iCustom. I consider this separation a safety feature: it means a buggy indicator can mislead you but cannot open positions. Keep the indicator honest and let the EA, with its own risk checks, do the trading.
How do I make my indicator run faster?
Respect the prev_calculated counter: compute only new bars and cache everything else. Avoid full-history loops on every tick, limit the bars your indicator processes, and keep heavy math out of OnCalculate's hot path. My first build used 14% CPU recalculating 5,000 bars per tick; the incremental version uses under 1% with identical output. Performance is a correctness issue — a lagging terminal misses fills.
Should I sell my custom indicator?
Only after it survives six months of your own live trading with honest, closed-bar logic. The market is flooded with repainting indicators showing fictional 80% win rates, and selling one — even unknowingly — destroys trust fast. Document the replay test, publish the honest win rate (mine is 55%), and price it on utility, not fantasy. A tool with a verified 55% win rate outsells a repainting 90% fantasy to anyone who has traded live.
What is the difference between an indicator and an EA in MT5?
Indicators analyze and display; EAs analyze and act. Technically: indicators run OnCalculate and draw to buffers but cannot trade, while EAs run OnTick and can send orders. In practice I use indicators for signal generation and visualization, and EAs for execution with risk management. WolfSignal started as an indicator and graduated to an EA input — the indicator answers "when," the EA answers "how much and how."
How many custom indicators should I run at once?
Fewer than you think. Each one adds CPU load and, worse, decision complexity — five indicators will always disagree about something. I run two on my main charts: the z-score signal tool and a session/volume context indicator. Every additional tool has to earn its place by changing a decision I would otherwise get wrong. If it only confirms what you already knew, it is decoration.
Where do I learn MQL5 indicator programming properly?
Start with the official MQL5 documentation's custom indicator section, then study one simple open-source indicator line by line before writing your own. The concepts that matter most — OnCalculate, indicator buffers, prev_calculated, closed-bar discipline — are all covered there. Expect your first build to repaint; mine did. Budget a month of testing before trusting anything, and run the replay test religiously.