Python 3 and a terminal. No MetaTrader, no broker, no account and no money.
macOS and Linux already include Python; on Windows install it from python.org with
“Add python.exe to PATH” ticked, then check with
python3 --version.
This page does not walk you around the charting interface. Menus move between versions and the platform documents its own buttons; what it does not explain is what the picture leaves out, which is where the surprises come from.
Nothing here is trading advice. The prices are generated, and the quotes in the last step are illustrative rather than live.
Understanding Chart Types
MT5 offers three fundamental chart types, each presenting price data differently:
- Bar Charts — Each bar shows the Open, High, Low, and Close (OHLC) for a time period. The left tick is the open price, the right tick is the close.
- Candlestick Charts — The most popular type. A filled (bearish) or hollow (bullish) body shows the range between open and close, with wicks showing the high and low. Candlesticks make price patterns visually obvious.
- Line Charts — A simple line connecting closing prices. Useful for seeing the overall trend without noise, but hides intra-period price action.
Most traders and all indicator developers use candlestick charts. They provide the most information at a glance and are the standard for technical analysis.
The 21 Timeframes
One of MT5's advantages over MT4 is its 21 timeframes (MT4 only had 9). Each timeframe determines how much time one candle represents:
Minutes: M1 (1 min), M2, M3, M4, M5, M6, M10, M12, M15, M20, M30
Hours: H1 (1 hour), H2, H3, H4, H6, H8, H12
Long-term: D1 (daily), W1 (weekly), MN1 (monthly)
Lower timeframes (M1-M15) show more detail but more noise. Higher timeframes (H4-MN1) show clearer trends but less precision for entries. Professional traders often use multiple timeframes — for example, analyzing the trend on H4 and timing entries on M15.
Navigating Charts
Essential chart navigation techniques:
- Zoom in/out — Use + and - keys, or the mouse scroll wheel
- Scroll history — Click and drag left to see older price data
- Auto-scroll — The green arrow button at the bottom-right keeps the chart pinned to the latest candle
- Chart shift — The double-arrow button adds empty space to the right of the last candle, useful for projection
- Crosshair — Press Ctrl + F or click the crosshair button to see exact price/time at any point
The Market Watch Window
The Market Watch panel (View > Market Watch or Ctrl + M) is your gateway to all tradeable instruments. It displays:
- Symbols tab — Real-time bid/ask prices, spread, and daily change for each instrument
- Ticks tab — Live tick-by-tick price feed for the selected instrument
- Details tab — Contract specifications: lot size, tick value, margin requirements, trading hours
To add an instrument to your chart, simply drag it from Market Watch onto the chart area, or right-click and select "Chart Window."
Adding Indicators to Charts
MT5 comes with 38 built-in technical indicators. To add one:
Press Ctrl + N or go to View > Navigator.
You will see categories: Trend, Oscillators, Volumes, Bill Williams, and Custom.
A settings dialog will appear where you can adjust parameters, colors, and the timeframe.
Templates and Profiles
Once you have configured a chart the way you like it (indicators, colors, timeframe), save it as a template so you can apply the same setup to any chart instantly. Go to Charts > Templates > Save Template.
Profiles save the entire workspace layout — all open charts, their templates, and window arrangement. Use profiles to switch between different trading setups (e.g., "Forex Scalping" vs "Stock Swing Trading").
Find Out What a Chart Is Not Showing You, in Three Steps
A chart is not a picture of the market. It is a summary of it, drawn from one of the two prices available, grouped into intervals you chose. Each of those three decisions throws information away, and each throws away something people later blame on their broker. In the next half hour you will measure exactly what a candle discards, watch the same four hours of trading look like three different markets, and find out why a stop can be hit at a price the chart never reached. Every line of output below came from running these files.
Go: open a terminal in a folder you can write to — cd ~/Desktop on macOS or Linux, cd %USERPROFILE%\Desktop on Windows.
Do: save this as candle.py and run python3 candle.py.
"""A candle is four numbers chosen from hundreds. See what it discards."""
import random
random.seed(4)
def ticks_for_bar(n=60):
t, p = [], 100.0
for _ in range(n):
p += random.uniform(-0.20, 0.20)
t.append(round(p, 2))
return t
ticks = ticks_for_bar()
o, h, l, c = ticks[0], max(ticks), min(ticks), ticks[-1]
print("ticks inside this one bar :", len(ticks))
print("the candle keeps : 4 numbers")
print(" open %.2f high %.2f low %.2f close %.2f" % (o, h, l, c))
print()
print("what the four numbers CANNOT tell you:")
print(" did the high come before the low? ->",
"high first" if ticks.index(h) < ticks.index(l) else "low first",
" (index %d vs %d)" % (ticks.index(h), ticks.index(l)))
print(" how many times did price cross the open?")
crossings = sum(1 for i in range(1, len(ticks))
if (ticks[i-1] < o) != (ticks[i] < o))
print(" ->", crossings, "times")
print(" how long was it above the open?")
above = sum(1 for p in ticks if p > o)
print(" -> %d of %d ticks (%.0f%%)" % (above, len(ticks), 100.0*above/len(ticks)))
print()
print("A candle is a summary, and every summary discards. The four numbers")
print("survive; the ORDER of everything that happened does not.")
print()
print("This is exactly the information a strategy tester lacks when it uses")
print("OHLC modelling -- and exactly what decides whether your stop or your")
print("target was reached first.")
You should see: sixty ticks reduced to four numbers:
ticks inside this one bar : 60
the candle keeps : 4 numbers
open 99.89 high 100.33 low 99.15 close 99.64
what the four numbers CANNOT tell you:
did the high come before the low? -> low first (index 42 vs 14)
how many times did price cross the open?
-> 11 times
how long was it above the open?
-> 17 of 60 ticks (28%)
A candle is a summary, and every summary discards. The four numbers
survive; the ORDER of everything that happened does not.
This is exactly the information a strategy tester lacks when it uses
OHLC modelling -- and exactly what decides whether your stop or your
target was reached first.
Sixty prices become four. What survives is the extremes and the endpoints; what is lost is the order of everything that happened — and the three questions the script asks are all questions about order.
The first one is the consequential one. The candle cannot say whether the high or the low came first, and that is precisely the fact that decides whether your stop or your target was reached when both were inside a single bar's range. It is the same gap that makes a strategy tester's cheaper modelling modes guess rather than know.
The other two are worth knowing about for a different reason: a bar in which price crossed its own open eleven times and spent only 28% of its life above it is not a “bullish” or “bearish” bar in any meaningful sense, whatever colour it is drawn.
If not: python3: command not found on Windows means Python was installed without
“Add python.exe to PATH”; try py candle.py. The figures are
seeded and will match this page.
Go: the same folder.
Do: save this as timeframe.py and run python3 timeframe.py.
"""The same data at three timeframes. The pattern changes; the data does not."""
import random
random.seed(4)
m1, p = [], 100.0
for _ in range(240):
o = p
p += random.uniform(-0.20, 0.20)
m1.append((o, max(o, p) + 0.05, min(o, p) - 0.05, p))
def group(bars, factor):
out = []
for i in range(0, len(bars) - factor + 1, factor):
chunk = bars[i:i+factor]
out.append((chunk[0][0], max(b[1] for b in chunk),
min(b[2] for b in chunk), chunk[-1][3]))
return out
def count_bullish(bars):
return sum(1 for o, h, l, c in bars if c > o)
def biggest_range(bars):
return max(h - l for o, h, l, c in bars)
for name, factor in (("M1", 1), ("M15", 15), ("H1", 60)):
bars = group(m1, factor)
print("%-4s bars %4d bullish %4d (%.0f%%) biggest range %.2f"
% (name, len(bars), count_bullish(bars),
100.0 * count_bullish(bars) / len(bars), biggest_range(bars)))
print()
print("Identical price history. Four hours of it, three ways.")
print()
print("The M1 chart has 240 decisions to make and 240 spreads to pay. The H1")
print("chart has 4. Neither is more 'true' -- they are the same ticks grouped")
print("differently, and the grouping is a choice about how often you act.")
print()
print("The biggest-range figure is the one worth noticing: a move that looks")
print("dramatic on M1 is a small part of one H1 candle. 'Volatility' as an")
print("eye impression is mostly a statement about the timeframe you chose.")
You should see: 240 bars, 16 bars and 4 bars from one set of prices:
M1 bars 240 bullish 117 (49%) biggest range 0.30
M15 bars 16 bullish 7 (44%) biggest range 1.14
H1 bars 4 bullish 2 (50%) biggest range 2.19
Identical price history. Four hours of it, three ways.
The M1 chart has 240 decisions to make and 240 spreads to pay. The H1
chart has 4. Neither is more 'true' -- they are the same ticks grouped
differently, and the grouping is a choice about how often you act.
The biggest-range figure is the one worth noticing: a move that looks
dramatic on M1 is a small part of one H1 candle. 'Volatility' as an
eye impression is mostly a statement about the timeframe you chose.
None of these is more real than the others. They are the same ticks grouped differently, so choosing a timeframe is not choosing a view of the market — it is choosing how often you act, and therefore how many spreads you pay.
The biggest-range column is the one worth sitting with. A 0.30 move fills an M1 candle and looks dramatic; the same move is a fraction of one H1 candle. Most of what people mean by “this market is volatile” is a statement about the timeframe they happen to be looking at, and zooming out is the cheapest way to test whether a move matters.
It also explains why the same strategy behaves differently on different timeframes even with identical settings: the edge per trade shrinks as the timeframe does, and the cost per trade does not.
If not: if all three rows show the same bar count, the grouping factor is not being applied
— the loop steps by factor and takes a chunk of that size.
Go: the same folder.
Do: save this as bidask.py and run python3 bidask.py.
"""The chart draws one line. There are always two prices."""
QUOTES = [("EURUSD", 1.10248, 1.10251), ("GBPUSD", 1.27010, 1.27016),
("XAUUSD", 2412.15, 2412.48), ("US500", 5432.1, 5432.6)]
print("%-9s %10s %10s %9s" % ("SYMBOL", "BID", "ASK", "SPREAD"))
print("-" * 42)
for sym, bid, ask in QUOTES:
print("%-9s %10.5f %10.5f %9.5f" % (sym, bid, ask, ask - bid))
print()
print("You BUY at the ask and SELL at the bid. So a position is negative the")
print("instant it opens, by exactly the spread.")
print()
sym, bid, ask = QUOTES[0]
print("open a buy on %s:" % sym)
print(" you pay : %.5f (the ask)" % ask)
print(" it is worth : %.5f (the bid, what you could sell at)" % bid)
print(" immediate P/L : %+.5f per unit" % (bid - ask))
print()
print("MetaTrader draws BID by default, so the candle you are looking at is")
print("not the price you will pay to buy. Turn on 'Show Ask line' in the")
print("chart properties and you will see a second line above it.")
print()
print("This matters most for stops. A BUY is closed at the BID, so a stop")
print("below the bid line is hit when the visible chart reaches it. A SELL")
print("is closed at the ASK, which is above the line you can see -- so a sell")
print("stop is triggered before the candle appears to touch it.")
print()
print("Anyone who has said 'my stop was hit but the chart never got there'")
print("has met this, and the chart was not lying.")
You should see: two prices per instrument and a position that starts negative:
SYMBOL BID ASK SPREAD
------------------------------------------
EURUSD 1.10248 1.10251 0.00003
GBPUSD 1.27010 1.27016 0.00006
XAUUSD 2412.15000 2412.48000 0.33000
US500 5432.10000 5432.60000 0.50000
You BUY at the ask and SELL at the bid. So a position is negative the
instant it opens, by exactly the spread.
open a buy on EURUSD:
you pay : 1.10251 (the ask)
it is worth : 1.10248 (the bid, what you could sell at)
immediate P/L : -0.00003 per unit
MetaTrader draws BID by default, so the candle you are looking at is
not the price you will pay to buy. Turn on 'Show Ask line' in the
chart properties and you will see a second line above it.
This matters most for stops. A BUY is closed at the BID, so a stop
below the bid line is hit when the visible chart reaches it. A SELL
is closed at the ASK, which is above the line you can see -- so a sell
stop is triggered before the candle appears to touch it.
Anyone who has said 'my stop was hit but the chart never got there'
has met this, and the chart was not lying.
There are always two prices: the bid, at which you can sell, and the ask, at which you can buy. MetaTrader draws the bid by default, so the candles you are looking at are not the prices you will pay to buy.
That single default explains one of the most common complaints in trading: “my stop was hit but the chart never got there”. A sell position is closed at the ask, which sits above the visible bid line by the spread — so its stop triggers before the candle appears to reach it. Nothing went wrong and the chart was not lying; it was drawing the other price.
Two things to do about it. Turn on the ask line in the chart's properties so you can see both, which takes seconds and permanently removes the confusion. And when placing a stop on a sell, allow for the spread — especially at the times step 3 of the backtesting page measured, when spreads widen to several times their usual size.
If not: these are fixed quotes and cannot vary. If the immediate profit prints as positive, the bid and ask were transposed — the ask is always the higher of the two.
Without scrolling up: a trader is upset that their sell position was stopped out at 1.2705 when the chart's highest candle that hour reached only 1.2703. They are convinced the broker moved the price. What actually happened, and what would you suggest they change? Answer: the chart was drawing the bid, and a sell position is closed at the ask — which is above the bid by the spread. Step 4 showed those two prices side by side: if the spread was around 0.0002 then a visible bid high of 1.2703 corresponds to an ask of about 1.2705, so the stop was reached exactly as specified even though the candle never appears to touch it. Nothing was moved. What to change: turn on the ask line in the chart properties so both prices are visible, and place stops on sell positions with the spread allowed for, remembering that spreads widen sharply around news and rollover. It is also worth checking the exact spread at that moment rather than the typical one — if the position was stopped during a data release, the gap between the two lines may have been several times its usual size, which is the same effect at a larger scale.
Now do it without the page: open any chart in your own platform, turn on the ask line in the chart properties, and watch the two lines during a quiet hour and then during a news release. The distance between them is your cost, and seeing it move is more convincing than any figure. Then take a single H1 candle you find interesting, switch to M1, and look at what happened inside it — step 2's point becomes obvious in a way no description manages.
Practical Tips
- Use the One Click Trading panel (Alt + T) for fast order execution during active trading
- Right-click any chart and select Properties to customize colors, grid visibility, and scale settings
- Use Ctrl + D to open the Data Window, which shows exact OHLCV values and indicator readings for the candle under your cursor
- Press F8 to quickly access chart properties