거래 로봇을 무료로 다운로드 하는 법을 시청해보세요
당사를 Telegram에서 찾아주십시오!
당사 팬 페이지에 가입하십시오
스크립트가 흥미로우신가요?
그렇다면 링크 to it -
하셔서 다른 이들이 평가할 수 있도록 해보세요
스크립트가 마음에 드시나요? MetaTrader 5 터미널에서 시도해보십시오
스크립트

OHLC Reality Check - at what stop distance does your backtest start lying? - MetaTrader 5용 스크립트

Petr Kostal
Petr Kostal
  • Algorithmic trading developer (MQL5 / MQL4) 에  Osvc
  • 체코
  • 366
Petr Kostal — algorithmic trading developer, Czech Republic.
I trade on live accounts myself, so I build EAs the way I'd want to run them.
What I build:
• Expert Advisors and indicators for MetaTrader 4 and 5 (MQL4 / MQL5)
조회수:
96
평가:
(1)
게시됨:
MQL5 프리랜스 이 코드를 기반으로 한 로봇이나 지표가 필요하신가요? 프리랜스로 주문하세요 프리랜스로 이동

Every backtest on 1-minute OHLC data makes one silent assumption: that inside a bar, price walked Open - Low - High - Close on a bullish bar and Open - High - Low - Close on a bearish one. It has to assume something, because OHLC data does not record the path. Real ticks do.

That assumption only matters when the bar that closes a trade touches both the stop and the target. Then the order decides whether the trade was a win or a loss, and the tester is guessing. This script measures how often the guess is wrong.

How it works. On every M1 bar it opens a virtual bracketed trade - one level above the bar open, one below, both the same distance away - and walks forward until price reaches one of them. If the closing bar touched only one level, there was nothing to decide. If it touched both, the script compares the tester's assumption with what the real ticks of that minute actually did.

The answer depends entirely on how wide the bracket is, so the script sweeps several distances and prints the curve. On XAUUSD, over 30 days and 27 844 virtual trades:

  • 20-point stop - 62.6 % of trades contested, 23.84 % resolved the wrong way
  • 50-point stop - 30.1 % contested, 8.25 % wrong
  • 100-point stop - 8.9 % contested, 1.66 % wrong
  • 200-point stop - 1.5 % contested, 0.18 % wrong
  • 500-point stop - 0.1 % contested, 0.00 % wrong
  • 1000-point stop - nothing contested, nothing wrong

"Contested" means the bar that closed the trade touched both levels, so the order decided the outcome. "Wrong" is the share of all resolved trades where the tester's assumed order was the opposite of what the ticks did - a win written down as a loss, or the reverse.

So the honest conclusion is not "OHLC always lies" or "OHLC is fine". The lie has a threshold, the threshold is symbol-specific, and you can measure it in eleven seconds instead of arguing about it.

Inputs. InpSymbol (empty = the chart symbol), InpDays, InpBrackets (the stop distances to sweep, in points), InpHorizonBars (how long a trade may stay open before it counts as unresolved), InpStepBars (open a trade every N bars, raise it on slow machines) and InpWriteCSV, which lists every mis-resolved trade with its entry time, its closing bar, what the model said and what the ticks said, so you can look at individual cases.

It reads history only. It never places an order and never touches an open position.

Requires real tick history for the symbol - download it in the Symbols window first, otherwise the contested trades cannot be decided.

Share of trades an OHLC backtest scores the wrong way round, by stop distance - XAUUSD, 30 days

SessionReopenEA SessionReopenEA

Gold has a daily maintenance break on the CME. The first hour after it rises more than chance explains, in every calendar year of an 11-year sample - while every other hour of the day measures flat. One trade per session, a volatility-scaled server-side stop, no averaging or grid. Then my cost model turned out to be wrong. A real-tick backtest showed the true round-trip cost at the reopen is about 60 points, not the 19 my research had charged - the M1 bar spread field is a per-bar summary and understates it roughly threefold. Re-running 11 years at the corrected cost: +3.34 bps, t 7.40, 59.3% wins -> +1.60 bps, t 3.42, 50.8% wins The edge survives, at less than half its original strength. That second number is the real one. What it is not: about +3.3% a year with 4.6% drawdown, roughly one year in nine negative. At 0.01 lots that is ~130 a year - a figure that measures the position size, not the strategy.

Trade Excursion Report: MFE and MAE of every closed trade, to CSV Trade Excursion Report: MFE and MAE of every closed trade, to CSV

Exports one CSV line per closed trade with the numbers a statement does not carry: the best unrealised profit the trade showed (MFE), the worst unrealised loss it survived (MAE), how much of the MFE was actually kept, how many bars it spanned, and how long it was held. Same measurement as the Trade Excursion indicator, written to a file instead of drawn, because the questions worth asking of this data are ones a chart cannot answer: does the capture ratio depend on the hour of entry? Are the trades I close early the ones I hold longest? Do losers on Mondays reach a different MAE than on Fridays? Those are one pivot table away once the CSV exists. Output is semicolon separated with a header row, in MQL5\Files; opens in any spreadsheet. Measurement limit: excursions come from bar highs and lows on the chosen timeframe; the path inside a bar is unknown. The bars column reports the resolution each trade got, and the summary counts single-bar trades separately instead of averaging them in.

CGoldSymbol - find the broker's gold and size the position correctly on it CGoldSymbol - find the broker's gold and size the position correctly on it

Detects the gold symbol whatever the broker calls it, reads the contract specification from the terminal instead of assuming it, and turns a risk in account currency into a lot size that is correct for that broker.

Gold Hour Profile - when gold moves, and when the spread eats it Gold Hour Profile - when gold moves, and when the spread eats it

Measures, hour by hour, how far a symbol travels and how much of that the spread takes away. Built for gold, works on any symbol, compares several side by side.