Module 1 — Markets, Instruments & the MT5 Context
Part I · Foundations (Fast Track) · Priority ⭐ Recommended · Status: Draft v0.1 Prerequisites: none (skim Module 0 for framing)
Overview
Everything you trade on MetaTrader 5 is a contract with your broker — not an asset held on an exchange. When you “buy EURUSD”, you are not exchanging euros for dollars in a public marketplace; you are opening a derivative position whose payoff tracks the interbank euro-dollar rate, against a counterparty who is, ultimately, your broker.
This single fact explains most of what makes MT5 trading distinctive:
- Why spreads vary by hour — your broker passes through (or marks up) a wholesale price that breathes with global liquidity.
- Why you pay or receive swap — every CFD position is financed overnight, like a margined position at a bank.
- Why some strategies are simply unavailable — there is no central order book to make markets in, and no funding rate to arbitrage on a crypto CFD.
- Why your backtest data looks slightly different from another trader’s — each broker’s feed is its own blend of wholesale prices.
💡 Idea: Treat your broker like a supplier with a price list, not like a neutral marketplace. Every strategy decision downstream — timeframe choice, session windows, cost ceilings — starts from the supplier’s actual price list, which this module teaches you to read programmatically.
By the end you will be able to produce a symbol spec sheet: one row per tradable instrument, containing contract size, tick value, minimum lot, spread by time of day, commission, and swap rates. Modules 4, 7, 8 and 22 all build directly on this artifact.
How MT5 Trading Actually Works
The journey of one order
Figure: where your market order actually goes after you click buy — and the fork where your broker decides whether to offset it externally or keep it in-house.
flowchart TD
you[Your terminal / EA / Python script]
server[Broker MT5 server]
lp[Liquidity providers<br/>banks, ECN venues]
internal[Broker's own book<br/>you trade against broker]
fill[Filled at broker-adjusted price]
confirm[Confirmation back to terminal<br/>journal updated]
you --> server
server --> check{How does the broker<br/>handle this symbol?}
check -->|"A-book: hedge externally"| lp
check -->|"B-book: keep in-house"| internal
lp --> fill
internal --> fill
fill --> confirm
classDef process fill:#f3f3f3,stroke:#888
classDef decision fill:#fff4d6,stroke:#d6a300
classDef ok fill:#e6f4ea,stroke:#2e7d32
classDef data fill:#e8f0fe,stroke:#4a86e8
class you,data data
class server,lp,internal,fill,confirm process
class check decisionHow to read this:
- The A-book / B-book fork is invisible to you. On the same account, some symbols may be hedged with real liquidity providers while others are netted internally (“bucketed”). This is legal and normal — it becomes a problem only when execution quality differs systematically between them.
- You never see the wholesale price. The feed on your chart is already the broker’s marked-up version of aggregated liquidity-provider prices.
- The confirmation loop is why slippage exists: the price moved between your click and the fill, and the broker fills you at the new price (market orders) or refuses (strict stop policies → “requotes”).
Account flavors in plain words
| Model | Who usually takes your trade | Spread profile | Typical commission |
|---|---|---|---|
| Dealing desk (“Market Maker”) | The broker itself | Fixed-ish, wider | Usually none |
| STP / ECN / Raw | External liquidity pool | Variable, tight | Yes, per lot |
Neither is automatically better. For a systematic trader what matters is the all-in cost curve (spread + commission + slippage) measured on your symbols at your trading hours — which is exactly what the Hands-On Project produces.
Margin and leverage, in accounting terms
Leverage is best understood as a deposit requirement, like posting collateral:
# Margin = notional value of position divided by leverage.
# Notional for 1 lot EURUSD = 100,000 EUR (the contract size).
contract_size_eur = 100_000
eurusd_rate = 1.0850 # EUR/USD quote
notional_usd = contract_size_eur * eurusd_rate # -> 108,500 USD
leverage = 100 # 1:100 account
margin_required_usd = notional_usd / leverage # -> 1,085 USD
Meaning: with $10,000 equity at 1:100, one EURUSD lot locks ~$1,085 as margin. Leverage does not change your risk per pip — a 10-pip adverse move costs $100 whether leverage is 1:30 or 1:500. It only changes how much capital sits idle as deposit, and therefore how many positions fit before a margin call or the broker’s automatic stop-out (forced liquidation when equity falls below a percentage of required margin).
⚠️ Pitfall: High leverage does not increase profits; it increases the number of simultaneous positions you can hold before the broker liquidates you. Most account blow-ups are position-sizing failures (Module 23), not leverage settings.
The Instrument Zoo on MT5
Each broker offers a menu drawn from these families. The economics differ enough that the same strategy idea can work on one family and fail on another.
| Family | Examples | Typical all-in cost | Clock | Distinctive quirk |
|---|---|---|---|---|
| FX majors | EURUSD, USDJPY | Lowest (pips-fraction + comm.) | 24/5 | Deepest liquidity, cleanest sessions |
| FX crosses/exotics | GBPJPY, USDTRY | Medium → very high | 24/5 | Wide tails, thin Asian-hours books |
| Metals | XAUUSD, XAGUSD | Low-medium | Near 24/5 | Gold trades like a risk-sensitive currency |
| Index CFDs | GER40, US500 | Medium (pts-based) | Exchange hours + extended | Cash-vs-futures basis drives opens |
| Energy CFDs | XBRUSD, XNGUSD | Medium-high | Exchange hours | Strong roll/carry behavior |
| Crypto CFDs | BTCUSD, ETHUSD | High | 24/7-ish (broker-dependent) | No funding rate (unlike exchanges); weekend gaps in liquidity |
Contract anatomy: lots, points, ticks, pips
Four numbers define every instrument’s mechanics, and all four arrive from one API call:
trade_contract_size— how much of the underlying one lot represents (EURUSD: 100,000 EUR; XAUUSD: commonly 100 oz).point— the smallest price increment the symbol quotes (10^-digits; EURUSD has digits=5, so point = 0.00001).pip— the conventional human unit: 10 points on 5-digit FX quotes. Pips are for conversation; points are for computation. Always compute in points.trade_tick_value— money gained or lost per one-point move of one lot, in your account currency. This single field converts price motion into P&L.
# Position P&L in MT5 is just: ticks_moved * trade_tick_value * lots.
# Worked example — 1 lot EURUSD, entry 1.08500, exit 1.08650:
entry, exit_price = 1.08500, 1.08650
point_size = 0.00001 # digits = 5
tick_value = 1.0 # USD per point per lot (typical EURUSD)
ticks_moved = (exit_price - entry) / point_size # -> 150 points
pnl_usd = ticks_moved * tick_value # -> +150 USD per lot
Meaning: on EURUSD, one point = $1 per lot, so the classic “$10 per pip” is just 10 points × $1. Gold behaves differently — verify, never assume:
# XAUUSD sanity check: contract 100 oz, quoted in USD with 2 digits.
gold_contract = 100.0 # oz per lot
gold_point = 0.01 # digits = 2
# One point move ($0.01 in gold price) on one lot:
gold_point_value = gold_contract * gold_point # -> $1.00 per point
# A $3.00 gold move = 300 points = $300 per lot.
🧪 Evidence: The Bank for International Settlements’ Triennial Survey puts spot FX turnover near $2.5 trillion per day (2022). EURUSD alone is roughly a quarter of it. This depth is why FX majors carry the lowest costs and why low-timeframe strategies are only realistic on the majors (Module 8).
Volume constraints you must respect
Brokers constrain position sizes to a grid: volume_min, volume_step, volume_max. Sizing logic must snap to this grid or orders get rejected:
# Snap desired risk-based size to the broker's allowed volume grid.
def snap_volume(raw_lots, v_min, v_step, v_max):
steps = round((raw_lots - v_min) / v_step) # nearest allowed step
snapped = v_min + steps * v_step
return min(max(snapped, v_min), v_max)
snap_volume(0.137, v_min=0.01, v_step=0.01, v_max=100.0) # -> 0.14
Broker Mechanics: Spread, Commission, Swap, Slippage
Every trade pays four tolls. Systematic profitability means budgeting all four before choosing a strategy — not discovering them afterward.
1. Spread — the visible toll
The ask is always above the bid; buying opens at ask, selling closes at bid, so every round trip starts one spread underwater. Spreads breathe with liquidity: tightest during the London/New York overlap, widest at the rollover hour and around news.
2. Commission — the honest toll
Raw-spread accounts charge per lot per side (commonly ~$3–3.50 per side per lot). Always compare brokers on spread + commission together — a “zero-commission” account with 1.2-pip EURUSD spreads loses to a raw account with 0.1 spreads + $7 round trip.
3. Swap — the overnight financing toll
Holding a leveraged position overnight is a financing arrangement: you either pay interest on the borrowed leg or receive interest on the lent leg — hence asymmetric swap_long / swap_short values, both frequently negative. Most brokers apply a triple charge on Wednesdays (covering the weekend when interbank settlement skips two days).
# Overnight financing cost for a held position (points-based swap convention).
lots = 1.0
swap_short_points = -12.5 # broker's swap_short for this symbol
point_value = 1.0 # USD per point per lot (EURUSD)
nights_held = 5 # Mon open -> Fri close
wednesday_surcharge = 3 # triple-swap day adds 2 extra charges
total_swap_usd = (nights_held + wednesday_surcharge - 1) \
* abs(swap_short_points) * point_value * lots
# -> 7 nights charged x 12.5 = 87.50 USD drag on the trade
Meaning: for swing systems holding days, swap can silently eat several pips per day — sometimes more than the spread. For pure intraday systems it is zero (no rollover crossing), which is one reason intraday and overnight strategies are genuinely different animals (Module 13).
4. Slippage — the invisible toll
Slippage is the gap between the price your system decided on and the price actually filled. It spikes predictably: news releases, the 00:00 server-time rollover, illiquid hours, and fast markets. Stops are especially exposed because they execute as market orders once triggered.
| Event | Typical spread/slippage behavior | Systemic response |
|---|---|---|
| London/NY overlap | Tightest spreads of day | Schedule entries here |
| Rollover (server midnight) | Spread blowout, thin books | Never hold pending orders across it |
| Red-folder news | Spreads widen 5–20×; requotes possible | Flatten or pause before release |
| Weekend gaps | Open far from Friday close | Size down before weekends if holding |
📌 Convention: In this curriculum, “cost” always means the all-in round-trip cost: spread + commission + expected slippage (+ swap if the holding crosses rollover). Module 22 builds the full measurement machinery.
The 24-Hour Liquidity Clock
FX never closes on weekdays, but it certainly breathes. Liquidity migrates around the globe with each financial center’s working day, and every symbol has a personality at each hour.
Figure: the daily liquidity relay. Each block hands momentum (and volatility character) to the next; the two shaded overlaps are the deep-water windows.
flowchart TD
sydney[Sydney 21-06 UTC<br/>thin, quiet opens]
asia[Tokyo 00-09 UTC<br/>JPY pairs active,<br/>ranges build]
london[London 07-16 UTC<br/>expansion, trends ignite]
overlap[London + NY 12-16 UTC<br/>deepest liquidity,<br/>tightest spreads]
ny[New York 12-21 UTC<br/>US data releases,<br/>late-day fades]
rollover[Rollover 21-22 UTC<br/>spread blowout,<br/>avoid trading]
sydney --> asia
asia --> london
london --> overlap
overlap --> ny
ny --> rollover
rollover --> sydney
classDef quiet fill:#e8f0fe,stroke:#4a86e8
classDef active fill:#e6f4ea,stroke:#2e7d32
classDef danger fill:#fde8e8,stroke:#c0392b
class sydney,asia,ny quiet
class london,overlap active
class rollover dangerHow to read this:
- The two green windows are prime time. The London morning expansion and the London/NY overlap carry most of the day’s directional movement and the tightest costs — the natural habitat of intraday strategies.
- Rollover (red) is a daily hazard, not a trading opportunity: spreads multiply, books empty, and stops get unfair fills.
- Session boundaries shift by an hour across daylight-saving changes — and your broker’s clock may not follow UTC (see the warning below).
| Session | Approx. hours (UTC, standard time) | Character |
|---|---|---|
| Sydney | 21:00 – 06:00 | Thinnest books; AUD/NZD moves |
| Tokyo | 00:00 – 09:00 | JPY crosses; ranges often form |
| London | 07:00 – 16:00 | Expansion phase; trend ignition |
| NY overlap | 12:00 – 16:00 | Peak liquidity; tightest spreads |
| Rollover | 21:00 – 22:00 | Widest spreads; avoid |
⚠️ Pitfall: Many brokers run their servers on GMT+2 in winter / GMT+3 in summer, deliberately so that the daily bar closes exactly at the New York 5pm close year-round. If you assume “broker time = UTC” anywhere in your pipeline, your session features will silently drift by one hour twice a year — and so will your live model’s inputs. Record your broker’s timezone rule in writing; Module 24 makes it a formal parity test.
For a low-timeframe trader, the clock is not trivia — it is the first feature of any system. An M5 breakout that works in the London window can bleed to death in Asian ranges purely from spread economics (Module 8); hour-of-day effects are strong enough to power standalone seasonal strategies (Module 13).
What MT5 Does NOT Give You
Knowing the boundary lines prevents weeks of wasted effort. MT5 is a superb retail gateway to OTC derivatives — it is not an exchange membership.
| Capability | True exchange market | Your MT5 account | Practical consequence |
|---|---|---|---|
| Central limit order book | Full depth, queue position | None — synthetic/partial depth at best | Market making on FX CFD is not real (extension track, CURRICULUM Appendix B) |
| Level-3 order flow | Visible | Not available | Microstructure strategies need LOB data elsewhere |
| Native options chains | Listed contracts | Rarely offered by MT5 brokers | Volatility track lives outside MT5 (Appendix B) |
| Crypto funding rates | Perpetual futures pay/receive funding | CFDs have swap, no funding mechanism | Funding-harvest arb requires an exchange API (ccxt) |
| Same-venue pairs trading | One consolidated tape | Each broker = private feed | Stat-arb is limited to synthetic pairs within one feed |
Two consequences deserve emphasis:
- Relative-value strategies must be synthetic. You cannot arbitrage an ETF against its basket on MT5; you can trade gold-vs-silver ratios or EUR-cross synthetics inside one consistent feed (Module 12).
- Crypto CFD ≠ crypto exchange. A BTCUSD CFD has no funding-rate cash flow and often wider spreads than a real exchange. Funding-harvest strategies belong on venues like Binance via API — same skills, different plumbing (Module 16).
💡 Idea: The broker feed being a private blend also means your backtests are internally consistent but not universal. A strategy validated on IC Markets’ XAUUSD feed is calibrated to that feed’s spread fingerprints. Porting it to another broker requires re-measuring costs — treat the feed as part of the strategy’s identity.
Options & Futures in One Page
A conceptual reserve for later modules — two instruments you will meet in reading even if you never trade them on MT5.
An option is an insurance contract. Buying a put is paying a premium so someone else absorbs your downside below a chosen level. Two prices matter:
- Realized volatility — how much the underlying actually moved (the storm that did or didn’t happen).
- Implied volatility — what the insurance market charges for future storms.
Sellers of options earn the persistent gap between the two prices — the variance risk premium — but wear tail risk when storms exceed the premium. That gap powers an entire institutional strategy family (Module 15, Appendix B’s Sinclair track).
A futures contract is a pre-paid forward commitment. Its price embeds the cost of carrying the underlying until expiry. When futures trade above spot (contango), long positions bleed a little each roll; below spot (backwardation), they collect. Roll yield explains why commodity index returns diverge so sharply from spot charts, and why trend systems on futures must handle rolls explicitly (Module 10).
Both topics are optional extensions for this curriculum — flagged here so their vocabulary never blocks your reading.
Building It In Python: Your Symbol Spec Sheet
The payoff of this module is mechanical: connect once, interrogate every symbol you might trade, and persist the result as the foundation cost table.
Snippet 1 — pull raw specifications (run inside a Python environment with the MetaTrader5 package installed and the terminal logged in):
import polars as pl
import MetaTrader5 as mt5
UNIVERSE = ["EURUSD", "GBPUSD", "USDJPY", "XAUUSD", "BTCUSD"]
mt5.initialize() # attaches to the running, logged-in MT5 terminal
rows = []
for sym in UNIVERSE:
info = mt5.symbol_info(sym)
assert info is not None, f"{sym} not visible — enable it in Market Watch"
rows.append({
"symbol": info.name,
"digits": info.digits,
"point": info.point,
"contract_size": info.trade_contract_size,
"tick_value": info.trade_tick_value, # acct ccy / pt / lot
"tick_size": info.trade_tick_size,
"volume_min": info.volume_min,
"volume_step": info.volume_step,
"spread_pts_now": info.spread, # instantaneous!
"swap_long": info.swap_long,
"swap_short": info.swap_short,
})
spec = pl.DataFrame(rows)
print(spec)
mt5.shutdown()
Note the trap hidden in plain sight: info.spread is this instant’s spread. A spec sheet built at 3pm London tells you nothing about Asian hours. That needs history.
Snippet 2 — derive the economics (pure arithmetic on the frame):
# All-in round-trip cost estimate, USD per lot, using typical raw-account terms.
COMMISSION_PER_SIDE_PER_LOT = 3.50
TYPICAL_SPREAD_PIPS = {"EURUSD": 0.2, "GBPUSD": 0.4, "USDJPY": 0.3,
"XAUUSD": 2.0, "BTCUSD": 25.0}
PIP_IN_POINTS = 10 # 5-digit FX and 2-digit metals quoting conventions
SPREAD_COST = pl.col("tick_value") \
* pl.col("symbol").replace_strict(TYPICAL_SPREAD_PIPS) \
* PIP_IN_POINTS
derived = spec.with_columns(
(SPREAD_COST + 2 * COMMISSION_PER_SIDE_PER_LOT)
.alias("roundtrip_cost_usd_per_lot")
)
print(derived.select(["symbol", "tick_value", "roundtrip_cost_usd_per_lot"]))
Snippet 3 — measure the breathing spread (the part everyone skips): sample ticks across several ordinary days and bucket by UTC hour:
from datetime import datetime, timedelta, timezone
import numpy as np
# Pull three mid-week days of ticks; bucket median bid-ask by hour.
end = datetime(2026, 8, 19, tzinfo=timezone.utc) # a Wednesday
start = end - timedelta(days=3)
ticks = mt5.copy_ticks_range("XAUUSD", start, end, mt5.COPY_TICKS_ALL)
# Convert tick epoch-milliseconds to UTC hour-of-day (0-23).
hour_of_day = (ticks["time_msc"].astype("datetime64[ms]")
.astype("datetime64[h]").astype(int)) % 24
spread_pts = (ticks["ask"] - ticks["bid"]) / 0.01 # gold quotes 2 digits
median_by_hour = {
int(h): float(np.median(spread_pts[hour_of_day == h]))
for h in np.unique(hour_of_day)
}
# Expect: trough 12-16 UTC, peak 21-22 UTC. If not, re-check DST assumption.
Testing it honestly
Before trusting the sheet, run four sanity checks:
- Tick-value sign and scale — EURUSD tick_value ≈ $1/point/lot on a USD account; if you see cents, the deposit currency isn’t what you assumed.
- Swap signs — most swaps are negative on both sides for retail symbols; a suspiciously positive swap deserves a look at the broker’s contract page.
- Spread shape — medians should trough in the London/NY overlap and spike at rollover. A flat hourly profile usually means you sampled too few days.
- Grid reconciliation — cross-check
contract_sizeand commissions against the broker’s published specification page; API values occasionally lag product changes.
Hands-On Project
Deliverable: data/cost_sheet.csv — one row per symbol, the foundation artifact for Modules 7, 8 and 22.
Required columns:
| Column | Meaning |
|---|---|
symbol, contract_size, tick_value, volume_min, volume_step |
Straight from symbol_info() |
spread_median_pips_asia / _london / _nyoverlap / _rollover |
From ≥ 10 sampled weekdays of ticks, bucketed by session |
commission_roundtrip_per_lot |
From account schedule (documented source) |
swap_long, swap_short, triple_swap_day |
From symbol_info() + broker page |
slippage_estimate_pips |
Rough initial guess (refined in Module 22) |
server_timezone_rule |
e.g. GMT+2/GMT+3 US-DST — written, not assumed |
Acceptance criteria:
- At least five symbols spanning ≥ 3 families (e.g., 2 FX majors, gold, one index or crypto CFD).
- Session spread medians computed from real tick history, not copied from marketing pages.
- Timezone rule documented and consistent with observed rollover hour.
- Every number traceable: script output, broker page, or written assumption.
- A short caveats note (what the sheet does not capture yet — e.g., news-time spread spikes).
Key Takeaways
- Everything on MT5 is a derivative contract against your broker; the feed, spread, swap, and available hours are all properties of that relationship, not of a neutral market.
- P&L arithmetic reduces to one line —
ticks_moved × trade_tick_value × lots— andtrade_tick_valueis the single field that converts price motion into money. - Cost is four tolls: spread, commission, swap, slippage. Strategies are chosen by the cost curve, never the other way around.
- The liquidity relay (Sydney → Tokyo → London → NY overlap → rollover) changes both signal quality and costs by the hour; session windows are strategy inputs.
- Your broker’s server clock is probably GMT+2/+3 with US DST, not UTC — record the rule now, test for it formally in Module 24.
- MT5 gives you no central order book, no native options, and no crypto funding rates — those strategy families need different venues, and knowing this early saves weeks.
- The symbol spec sheet built today is the curriculum’s first reusable artifact; Modules 7, 8 and 22 consume it directly.
References
- MetaQuotes — MetaTrader5 Python package: symbol_info (field definitions used throughout this module)
- MQL5 Reference — Environment state: SymbolInfo (contract-property semantics, swap conventions)
- Larry Harris — Trading and Exchanges (Oxford University Press) — dealer markets, why spreads exist, who takes the other side
- Bank for International Settlements — Triennial Central Bank Survey: FX turnover — scale-of-market evidence cited above
- ThinkMarkets Academy — Forex market hours: sessions & overlaps — session-clock reference (vendor-neutral summary)
- Next in sequence: Module 2 — Statistics Refresher