Engineering note · Signal acceptance
Pine and MT5 Signals Differ: Check the Candles First
A buyer asks for a Pine signal in MT5. The two charts look close, but the markers do not land on every same hour. Before changing the formula, compare the exact candles and the time each platform assigned to them. One owned EURUSD H1 example makes that check reviewable across the full August 2026 overlap.
- 01Freeze the rule
- 02Align closed bars in UTC
- 03Read every mismatch
- 04Agree the acceptance boundary
Fix the question before comparing screenshots
The example rule is a strict SMA(3)/SMA(5) crossover on completed hourly bars. A bullish marker needs the fast average to cross above the slow average; a bearish marker needs the opposite crossing. That rule was fixed before the comparison. If one side reads a forming bar, changes the comparison operator or takes a higher-timeframe value early, equal-looking plots cannot establish equal signals.
Freeze the full symbol, timeframe, calendar window and source version. TradingView used OANDA:EURUSD H1. MT5 used EURUSD H1 on HolaPrime-Server1. These are two price feeds, even though both are labelled EURUSD. A screenshot is useful to locate a marker. The exported rows carry the time, direction and OHLC values needed to explain it.
Align by UTC, then keep the missing history visible
Server clock labels and chart display zones can shift what looks like the same bar. Convert both timestamps to UTC before pairing rows. Compare only shared, completed hourly bars, and keep a separate list of bars present on just one side. Do not move a marker to an adjacent row to make the counts match.
The owned August comparison has 507 shared bars. The observed Pine and MT5 signal states match on 491 and differ on 16. TradingView shows 116 signal markers and MT5 shows 112. The first five TradingView bars lack enough earlier exported history for a separate local SMA formula check. Those bars stay in the observed comparison; the formula check for them is marked unverified rather than silently discarded.
The comparison script reads exported markers from each platform. It does not generate a replacement Pine series and then call that parity. The table keeps both feeds’ OHLC and SMA values beside each mismatched timestamp, so the first divergence can be inspected without trusting a visual overlay alone.
- One row: normalized UTC bar time and both source candle values.
- One rule: strict completed-bar crossover and a stated warm-up requirement.
- One result per side: bullish, bearish or no marker.
- One explanation for each row where those results differ.
Explain the sixteen rows, not just the total
Twelve mismatch rows are six crossings that landed one hour apart between the feeds. Four rows are two brief bearish-then-bullish crossings visible only on the OANDA TradingView feed. Small OHLC differences moved an average across the strict crossover threshold. The linked discrepancy log names the close and average values for every one of those rows.
That finding does not make either platform wrong. It shows why a raw marker count is a weak acceptance test when source candles differ. A port can implement the agreed rule correctly on its own feed and still print a different observed marker. Conversely, a feed explanation must not be used to excuse a logic defect. Run a separate controlled-candle fixture on both implementations if code-level equivalence is the acceptance claim.
Do not trim August to a week where all markers happen to agree. Keep the full selected window, including no-signal bars and the mismatches. A useful handoff names which differences came from clock mapping, which from input candles and which remain unexplained. If one remains unexplained, it is an open defect or an open rule decision, not a pass.
Choose an acceptance rule the buyer can actually verify
There are two legitimate questions. Does the MT5 implementation produce the same decisions from the same frozen OHLC input? Or does it reproduce the TradingView markers while using a different live broker feed? The first is a code-parity test. The second also depends on the feed and any agreed tolerance. Write which one is required before calling a port accepted.
For a bounded port, retain the source version, one positive crossing, one negative crossing and one no-signal or boundary case with expected timestamps. Include a still-forming-bar case if the Pine source can evaluate intrabar. If the buyer needs higher-timeframe data or session filters, freeze those rules separately; this simple SMA example does not prove them.
The observed August case proves a narrower result: signal states were compared on the same 507 shared UTC bars and each of the 16 differences has a bar-level account. It does not test fills, profit, another symbol, another month or a private Pine script. That boundary is what makes the proof useful for deciding the next test.
Three acceptance checks
Proposed tests, not executed customer results. Record actual outcomes separately.
Clock and row alignment
Input: Export one full named period of completed bars from both platforms with raw source time, UTC time, direction and OHLC.
Expected: Every shared UTC hour has one row per source. Unshared or warm-up bars remain labelled; no signal is shifted to hide a mismatch.
First divergent crossover
Input: For one mismatched hour, freeze the preceding candles and the strict SMA(3)/SMA(5) rule on both feeds.
Expected: The table shows both OHLC sets, average values and observed marker states. A feed difference or logic difference is named from those values.
Controlled input parity
Input: Run each implementation on the same authorized closed-bar OHLC fixture with bullish, bearish and no-signal rows.
Expected: Markers agree on the frozen input under the written timing rule, or the first different decision is retained as a failing case.
Sources and related guides
Start with your own rules
Write down which signal and timing rule you need before requesting a port. The free Rule Check helps expose missing decisions; it does not certify a strategy.
Run the free Rule Check →