Backtesting Platforms Compared: MT5, TradingView, Python
A side-by-side look at backtesting platforms for retail and prop traders: data quality, fill modeling, cost, and when a custom Python engine is worth it.
Backtesting Platforms Compared: MT5, TradingView, Python
TLDR
A backtesting platform replays historical market data through your trading rules and reports what would have happened under its model of fills, costs and data. The four options most retail and prop traders actually choose between are the MT5 Strategy Tester (free, tick-level, tied to MetaTrader), the TradingView strategy tester (built into the charting platform you may already pay for, bar-based with optional intrabar refinement on higher plans), Backtrader (free open-source Python framework) and a custom Python engine built around libraries such as pandas or vectorbt. None of them is "most accurate"; each models a different slice of reality, and the right one is the one whose blind spots do not overlap with your strategy's edge.
What a backtest can and cannot tell you
Every backtest is a simulation with four inputs: the price data, the rules, the execution model (when and at what price orders fill) and the cost model (spread, commission, slippage, swap). Platforms differ mainly in the first and third. Before comparing them it is worth stating plainly what no platform fixes:
- Overfitting. If you tuned parameters on the same data you are testing, the result is a description of the past, not a forecast. The platform cannot know how many variants you tried.
- Survivorship and symbol changes. Equity universes drop delisted names; futures contracts roll; brokers change CFD specifications. Your data has to reflect the world as it was.
- Liquidity. A test that assumes you can trade 50 lots at the printed price on a thin pair is fiction regardless of tick resolution.
- Regime change. Markets change. A clean ten-year curve says the rules fit ten years of history.
With that said, the platform does determine whether a test is even internally honest, and that is the comparison that follows.
Comparison table
| Platform | What it is | Languages / platforms | Data and fill model | Pricing model | Trial / refund | Lock-in | Who it suits |
|---|---|---|---|---|---|---|---|
| MT5 Strategy Tester | Backtester and optimizer built into MetaTrader 5 | MQL5; runs the same EA you trade live | Broker tick or minute data; "every tick based on real ticks" mode where the broker supplies ticks; models spread from history, swaps, commissions if configured; multi-symbol and multi-timeframe; genetic and full optimization; distributed agents | Free with any MT5 install; optional paid compute via MQL5 Cloud Network, billed per use (see mql5.com cloud pricing) | Not applicable | Results and EA are MetaTrader-specific; data is your broker's | Anyone who will trade the strategy through MT5, especially forex, CFD and prop-firm traders |
| TradingView strategy tester | Backtester built into TradingView charts | Pine Script | TradingView's consolidated bar data; fills modeled on bar OHLC with optional "bar magnifier" intrabar refinement on higher plans; "deep backtesting" for longer history on higher plans; commission and slippage set in strategy properties | Included with TradingView plans; bar count, history depth and magnifier depend on tier (tradingview.com pricing page) | See pricing page | Pine Script is TradingView-only; results depend on their data feed | Traders who develop in Pine, trade from TradingView alerts, or want fast visual iteration |
| Backtrader | Open-source Python backtesting framework | Python | Any data you load (CSV, pandas, broker feeds); bar-based event loop with configurable order execution, slippage and commission schemes; supports multiple data feeds and timeframes; resampling and replay | Free (open source) | Not applicable | None; code and data are yours. Upstream development has been quiet for several years, so community forks and self-maintenance matter | Python-literate traders who want a full event-driven engine without building one |
| Custom Python engine | A backtester you or a developer write around pandas, NumPy, vectorbt or similar | Python | Whatever you implement; vectorized for speed or event-driven for fidelity; arbitrary data sources, including tick and order-book data | Development time; libraries are free; optional paid data | Depends on the developer's terms | None | Strategies that no off-the-shelf tester models correctly, portfolio-level research, or teams that need the engine to be inspectable |
| Also worth knowing: QuantConnect LEAN, NinjaTrader, AmiBroker, MultiCharts | Cloud and desktop testers with their own ecosystems | C#/Python (LEAN), C# (NinjaTrader), AFL (AmiBroker), EasyLanguage/PowerLanguage (MultiCharts) | Vary; LEAN and NinjaTrader support tick-level replay; AmiBroker is fast for portfolio-level bar tests | LEAN is open source with paid cloud tiers; NinjaTrader free for charting and testing with paid licenses for live; AmiBroker and MultiCharts are paid licenses. See each vendor's pricing page | See pricing pages | Each has its own scripting language | Mentioned for completeness; choose if you already live in that ecosystem |
MT5 Strategy Tester in detail
The Strategy Tester runs the compiled EA you will trade, against the symbol specifications of the broker you are connected to, with the broker's historical ticks where available. That last point is the big one: it is the only option here where the thing you test and the thing you deploy are literally the same program on the same broker's data. Our backtesting service starts here for any MetaTrader project for that reason.
Modeling modes. "Every tick based on real ticks" replays the broker's stored tick history, including historical spread. "Every tick" generates synthetic ticks from minute bars. "1 minute OHLC" and "Open prices only" trade speed for fidelity and are fine for strategies that act only on bar close. Choosing the wrong mode is the most common tester mistake we see: a scalping EA tested on open prices only is meaningless, and a daily-bar system tested on real ticks is just slow.
Costs. Spread comes from history in real-tick mode or can be fixed. Commission and swaps are taken from the symbol specification if the broker publishes them; otherwise you set them. Slippage beyond the historical spread is not modeled by default, so for market-order strategies you should add a slippage assumption in the EA or stress the results.
Optimization. Full grid and genetic search over inputs, with forward testing (optimize on one window, test on the next) built in. You can distribute across local CPU cores and rent additional agents on the MQL5 Cloud Network, which is billed per use; current rates are on mql5.com. Custom optimization criteria are possible through the OnTester function, shown later.
Weak points. Tick history depth and quality depend entirely on the broker; some have years, some have months, some have gaps. Multi-currency testing works but is slower and more memory-hungry. Reporting is functional rather than analytical; you will export to Python or a spreadsheet for anything beyond the standard report. And it only tests MQL5, so a Pine strategy must be converted first (Pine Script to MQL5 conversion).
TradingView strategy tester in detail
If you write in Pine, this is where you will test first, and for good reason: iteration is immediate, the trades draw on the chart, and the report is readable. For how strategies connect to execution see TradingView webhooks and automation.
Fill model. By default the tester sees only each bar's open, high, low and close and makes assumptions about the path between them. Where a bar contains both your stop and your target, it has to guess which hit first. Bar magnifier, available on higher-tier plans per TradingView's pricing page, uses lower-timeframe bars to resolve this. Deep backtesting, also tier-dependent, extends history beyond the bars loaded on the chart. Check the pricing page for which tier includes which.
Costs. Commission and slippage are strategy properties and default to zero, which is why so many published Pine backtests look wonderful. Set both before you believe anything.
Repainting and lookahead. Strategies that use request.security without care, or that act on unconfirmed bars, can show results that could never have been achieved live. Our non-repainting indicators article covers the mechanics. The tester will not warn you; it will cheerfully report the impossible.
Weak points. Data is TradingView's consolidated feed, not your broker's, so spreads and even prices differ from what you will trade. No multi-symbol portfolio testing in one strategy. Optimization is manual or via limited input stepping; there is no built-in genetic optimizer. History depth and bar limits are plan-dependent.
Backtrader in detail
Backtrader is an event-driven Python framework: you write a Strategy class with next() called per bar, add data feeds, set a broker model with commission and slippage schemes, and run. It supports multiple feeds, resampling, replaying higher timeframes bar by bar, analyzers for statistics, and plotting.
Strengths. It is free, it is expressive, and the broker model is more honest than most bar-based testers because you configure slippage and commission explicitly and can model order types in detail. You bring your own data, which means you can test on your actual broker's export.
Weak points. Upstream development has been quiet for several years; it still works on current Python in our experience, but you should expect to maintain your environment and lean on community forks. It is bar-based; true tick replay is possible but awkward. It is single-threaded and slow for large parameter sweeps compared with vectorized approaches. And nothing it produces deploys anywhere by itself; going live means rewriting the logic for your execution platform, which is a second chance to introduce differences.
Custom Python engine in detail
"Custom Python" covers a range from a 200-line vectorized pandas script to a full event-driven engine with an order book simulator. The common thread is that you decide the model. This is what we build in our quant development work when a client's strategy does not fit any tester's assumptions.
When custom is not worth it
- Your strategy trades one symbol on bar close with standard stops. MT5 or TradingView already models that correctly and for free.
- You want a backtest to decide whether to pursue an idea at all. Prototype in whatever is fastest; a custom engine is for ideas that have already earned attention.
- You cannot read Python. An engine you cannot inspect is just another black box, and you have paid more for it.
- The appeal is speed alone. vectorbt and similar libraries give vectorized speed for ordinary strategies without a bespoke build.
When custom is worth it
- Portfolio logic. Position sizing across dozens of symbols with shared risk budgets, correlation-aware exposure limits, or capital allocation between sub-strategies.
- Non-standard data. Order-book snapshots, funding rates, options chains, alternative data joined to prices.
- Execution that matters. Queue position for limit orders, partial fills, latency assumptions, exchange-specific order types. Bar-based testers cannot represent these.
- Research at scale. Thousands of parameter sets, walk-forward with many windows, bootstrapped confidence intervals on metrics. You want the engine to be a library you call, not a GUI you click.
- Auditability. Teams that need to explain exactly how every fill was modeled benefit from owning the code.
Worked example: one strategy, two testers, different answers
Consider a mean-reversion rule on a forex pair, 15-minute bars: buy when RSI(14) falls below 25, exit at RSI above 55 or a stop of 2 times ATR(14), one position at a time, fixed 1 lot. The numbers below are illustrative, chosen to show mechanics, and are not from any real test.
Run it in TradingView with default properties: commission zero, slippage zero, bar OHLC fills. Suppose it reports 400 trades over the sample with average profit per trade of 1.2 pips. Now set commission to a realistic round-trip figure for your broker and slippage to one tick; a 1.2 pip average edge before costs becomes negative after a 1.5 pip round-trip cost. Nothing about the data changed; the cost model did. This is arithmetic, not a finding: 1.2 minus 1.5 is negative 0.3 pips per trade.
Run the same rule in the MT5 Strategy Tester on your broker's real ticks. Historical spread is now applied tick by tick. Mean-reversion entries happen at volatile moments when spreads widen, so the effective cost per trade is often higher than the broker's advertised typical spread. Expect the result to differ from TradingView's again, and in the same direction. The platform that most resembles your live broker is the one to trust more, which for an MT5 trader is MT5.
The lesson generalizes: whenever two testers disagree, the disagreement is information about which assumption your edge depends on. If it only survives with zero costs, you have learned something valuable cheaply.
Code: making each tester honest
Two short snippets that address the most common honesty gaps. First, a Pine Script v6 strategy header that sets costs and only acts on confirmed bars:
//@version=6 strategy("RSI reversion (costed)", overlay=false, initial_capital=10000, default_qty_type=strategy.fixed, default_qty_value=1, commission_type=strategy.commission.cash_per_contract, commission_value=0.00007, slippage=1, calc_on_every_tick=false, process_orders_on_close=true)rsiLen = input.int(14, "RSI length") buyLvl = input.int(25, "Buy below") exitLvl = input.int(55, "Exit above") atrMult = input.float(2.0, "Stop ATR multiple")
r = ta.rsi(close, rsiLen) atr = ta.atr(14)
// barstate.isconfirmed: no decisions on a still-forming bar if barstate.isconfirmed and strategy.position_size == 0 and r < buyLvl strategy.entry("L", strategy.long) strategy.exit("X", from_entry="L", stop=close - atrMult * atr)
if barstate.isconfirmed and strategy.position_size > 0 and r > exitLvl strategy.close("L")
plot(r, "RSI") hline(buyLvl) hline(exitLvl)
The commission value above is a placeholder in price units per contract; replace it with your broker's figure. The point is that it is not zero.
Second, an MQL5 OnTester function that makes the optimizer rank results by something more defensible than net profit. Here it rewards profit per unit of maximum drawdown and penalizes small samples:
// MQL5 - custom optimization criterion for the Strategy Tester // Select "Custom max" as the optimization criterion in the tester settings. double OnTester() { double profit = TesterStatistics(STAT_PROFIT); double maxDDPct = TesterStatistics(STAT_EQUITY_DDREL_PERCENT); double trades = TesterStatistics(STAT_TRADES);if(trades < 100) return 0.0; // too few trades to mean anything if(maxDDPct <= 0.0) return 0.0; // degenerate run if(profit <= 0.0) return 0.0;
// profit per percent of relative equity drawdown double score = profit / maxDDPct;
// mild penalty for low trade counts between 100 and 300 double sampleFactor = MathMin(1.0, trades / 300.0); return score * sampleFactor; }
The thresholds (100 and 300 trades) are choices, not laws. The value of the function is that it forces you to write your acceptance criteria down and apply them identically to every optimization pass.
A process that works on any platform
- Get the right data. Your broker's export for anything you will trade through that broker. Check for gaps and duplicate bars before testing anything.
- Set costs first. Spread, commission, slippage, swap. Zero is never the right default.
- Split the data before you look at it. Keep the most recent segment untouched until you have finished tuning.
- Test on the slowest mode you can afford for the final run (real ticks in MT5, bar magnifier in TradingView, finest data you have in Python).
- Walk forward. Optimize on window one, test on window two, roll. If performance collapses out of sample, the parameters are describing noise.
- Stress the assumptions. Double the slippage. Remove the best ten trades. Shift entries by one bar. An edge that survives this treatment is more believable.
- Forward test on demo with the deployment platform before any live capital, however small the backtest's warts.
Choosing in practice
- You trade through MT4 or MT5: use the MT5 Strategy Tester as the final word, whatever you prototype in.
- You develop in Pine and execute via alerts: use TradingView's tester with realistic costs and bar magnifier if your plan has it, and understand that live fills come from a different data feed.
- You are comfortable in Python and want to own the model: start with Backtrader or vectorbt; move to a custom engine only when they cannot express your strategy.
- You run a portfolio, use unusual data, or need to explain every fill: budget for a custom engine and treat it as infrastructure.
FAQ
Which backtesting platform is the most accurate?
Accuracy is relative to the venue you will trade. For an MT5 broker account, the MT5 Strategy Tester on that broker's real ticks is closest to live. For a strategy executed from TradingView alerts into a different broker, no tester matches live exactly and you should forward test. "Most accurate" in the abstract is not a meaningful question.
Is the TradingView strategy tester reliable?
It is reliable at what it models: bar-based fills on TradingView's data with the costs you configure. Problems arise from zero default costs, intrabar ambiguity without bar magnifier, and repainting logic. Fix those three and it is a reasonable prototyping tool.
Is Backtrader still maintained?
Upstream activity has been low for several years. The library continues to work for many users and community forks exist, but you should plan to maintain your own environment rather than expect fixes from upstream.
Do I need tick data to backtest?
If your strategy's decisions or exits depend on what happens inside a bar (tight stops, scalping, intrabar entries), yes. If it acts only on bar close with stops wider than typical bar ranges, minute bars are usually sufficient. Match the data resolution to the decision resolution.
How many trades make a backtest meaningful?
There is no universal number, and anyone who gives you one is guessing. More trades narrow the uncertainty around the average; fewer widen it. Our OnTester example uses 100 as a hard floor and 300 as a comfort level for intraday systems, and those are judgments you should adjust to your trade frequency and holding period.
Can you backtest a prop-firm challenge?
You can simulate the rules (daily loss, max drawdown, consistency) on top of a strategy's trade list, which is a useful exercise. See prop firm EA rules for what to encode. It tells you how often the rules would have been breached historically, not whether you will pass.
Where Viprasol fits
Our backtesting and strategy development service builds honest tests in the MT5 Strategy Tester, TradingView or Python depending on where you will trade, including data validation, cost modeling, walk-forward and custom optimization criteria. For research that outgrows off-the-shelf testers we build custom engines, and we will tell you when a free tool is the right answer instead. Ranges are on the pricing page; describe your strategy on the contact page.
Trading involves substantial risk of loss. Backtested results are hypothetical and do not predict future performance. Nothing here is financial advice.
External Resources
About the Author
Viprasol Tech Team
Custom Software Development Specialists
The Viprasol Tech team specialises in algorithmic trading software, AI agent systems, and SaaS development. With 1000+ projects delivered across MT4/MT5 EAs, fintech platforms, and production AI systems, the team brings deep technical experience to every engagement.
Ready to Automate Your Trading?
Discuss a custom Expert Advisor with defined strategy rules, risk controls and a testing plan.
Free consultation • No commitment • Response within 24 hours
Need a custom EA or trading bot built?
We build MT4/MT5 Expert Advisors around your strategy, broker and risk requirements. Each project has an agreed scope, testing plan and individual quote.