Backtesting in HorizonAI
Python mode has its own backtester, and it is the quickest one in HorizonAI. It runs synchronously against candles we already have — there's no worker queue and no terminal to boot, so a result comes back in a couple of seconds. Better still, the assistant can run it itself in the middle of a reply and read the numbers straight back into the conversation.
What it is
A vectorized backtest engine built into the Python sandbox. Your script declares entries and exits with set_long_entry, set_long_exit, set_short_entry and set_short_exit; the engine walks the candles, applies your stops and targets, and returns a full report — profitability, risk, trade analysis, an equity curve, a drawdown curve, monthly returns, a P&L distribution and every closed trade.
The differentiator versus the MT5 backtester isn't just speed. MT5 queues a job on a real terminal and you wait. Python runs in-process, and because it's in-process the assistant has a tool for it — so "backtest this and tell me what's wrong with it" is a single turn, not three.
1) Write a strategy, not an indicator
An indicator has nothing to simulate. Your script has to declare at least one entry:
- Open a Python chat at app.horizontrading.ai.
- Ask for a strategy, e.g. "Go long when the 20 EMA crosses above the 50, exit on the reverse cross, 2% stop and 3% target."
- The assistant writes the entries and exits alongside the chart drawing, so the same script both plots and backtests.
2) Open the Backtest tab
In the right-side panel, switch from Code to Backtest. The controls row holds three sub-tab buttons (Overview, Report, Trades), the symbol picker, the timeframe picker and the Run button.
Symbol and timeframe are the same pair the Chart tab uses — change them in either place and both follow.
3) Pick a symbol and timeframe
The symbol box opens on a curated list and searches a much wider universe as you type:
- Forex — EUR/USD, GBP/USD, USD/JPY, USD/CHF, AUD/USD, USD/CAD
- Commodities — XAU/USD (Gold), XAG/USD (Silver)
- Crypto — BTC/USD, ETH/USD, SOL/USD, DOGE/USD, AVAX/USD, LINK/USD
- Stocks — AAPL, MSFT, GOOGL, AMZN, TSLA, NVDA, META
Timeframes: 1m, 5m, 15m, 30m, 1h, 4h, 1D.
There are no date pickers. The window is fixed at roughly the most recent 730 bars on intraday timeframes and 1,825 bars on 1D — the Report tells you exactly how many bars were tested.
4) Click Run
Hit Run. Most runs finish in a few seconds. Symbol and timeframe lock while a run is in flight so an incoming result can't get labelled with the wrong instrument.
5) Read the results
Three sub-tabs:
- Overview — the read-at-a-glance view. Net profit and the balance it came from, return, profit factor, expectancy, win rate, Sharpe/Sortino/Calmar, max drawdown, trade count and bars tested, a long-vs-short split, how trades ended, and the equity curve.
- Report — the formal, exhaustive version: gross profit and loss, profit factor, expectancy, recovery factor, max drawdown, average and largest win/loss, win/loss ratio, winning and losing counts, max consecutive wins and losses, trade durations, exposure, long vs short P&L, starting capital and final equity — plus monthly returns, the P&L distribution, an exit-reason breakdown and a drawdown-over-time chart.
- Trades — the price chart with your entry and exit markers drawn on it, above a sortable table of every closed trade: direction, entry and exit time and price, duration, P&L in dollars and percent, and why it closed (stop, target, signal, or end of data).
Exports: the Report header has a JSON button for the whole result; the Trades tab has a CSV button for the trade list.
6) Iterate
The assistant can see the metrics, the trade list and your code at the same time, so ask it directly: "why is the drawdown so deep?", "try a wider stop", "does it still work on gold?" It will edit the strategy and offer to run it again.
Limits, defaults & fine print
- Who can run it: running a backtest requires Pro or Elite. On other plans the Run button shows an upgrade panel instead of a result — writing and charting Python stays free.
- Starting capital: $10,000, fixed.
- Commission: 0.1% per trade, charged on entry and on exit.
- Slippage: none modelled.
- Execution: bar close. One position at a time — a new entry only fires when flat.
- Position size: a fraction of current equity, 100% by default; stops and targets take a percentage or a series of absolute prices.
- Any open position is closed at the last bar and appears in the trade list with an "end of data" reason.
- Timeout: 30 seconds per run.
- Sharpe, Sortino and Calmar are annualised on a 252-period assumption regardless of the timeframe you ran, so treat them as comparative, not absolute.
- No queue and nothing persisted per run — results are cached briefly and re-shown, not archived as a job history.
When to use this vs. the MT5 backtester
| Use the Python backtester when… | Use the MT5 backtester when… |
|---|---|
| You're still deciding whether the idea is worth anything | You want the numbers a real MetaTrader 5 terminal produces |
| You want the assistant to run it and iterate in one turn | You want broker-realistic spread on real MT5 tick history |
| You want an answer in seconds, not a queue position | You're testing an Expert Advisor you'll actually deploy to MT5 |
Most people do both: prove the edge in Python, then export to MQL5 and re-test it on MT5 before going anywhere near live.
Troubleshooting
- "This script has no entries, so there is nothing to backtest" — the script only draws. Ask for
set_long_entry/set_short_entryto be added. - Zero trades, everything reads $0 — the entry condition never became true in the window. Loosen it, try a more volatile symbol (XAU/USD is a good stress test), or move to a lower timeframe for more bars.
- "Backtest timeout (max 30 seconds)" — usually a loop over bars. Ask the assistant to "rewrite this vectorized."
- The Run button shows an upgrade panel — backtesting is on Pro and Elite. The Chart tab still works on your plan.
- Profit factor reads ∞ — there were winning trades and no losing ones. It's a sample-size problem, not an edge.
- "Couldn't load market data" — that listing has no history available. Pick another symbol from the curated list.
Understanding Your Results
- Backtesting Metrics Explained — Profit factor, Sharpe, drawdown, expected payoff
- How to Backtest a Trading Strategy — Validation best practices
- Common Backtesting Mistakes to Avoid — Curve-fitting, look-ahead bias, and other traps
Related Guides
- Python Mode — What the sandbox gives you and what it won't
- Export Python to Pine, MQL5 or NinjaScript — Move a proven strategy to your platform
- Backtesting MT5 Strategies in HorizonAI — The real-terminal backtest
- Backtesting Pine Script Strategies in HorizonAI — Run it in your own TradingView account
- How to Talk to Horizon AI — Prompt tips for better strategies