An MQL5 Expert Advisor is an event-driven program in MetaTrader 5. It can evaluate rules and submit trade requests when the required permissions are enabled. Event processing, permissions and server responses must be distinguished from successful execution; attaching a program to a chart does not itself establish any trading result.

What an Expert Advisor in MQL5 actually is

MetaEditor compiles source MQ5 into executable EX5. The compiled file can be distributed without its source; learning MQL5 does not reveal an undisclosed algorithm inside a purchased EX5. Expert Advisors can submit permitted trade requests. Indicators can calculate or notify but have different events and prohibited trade functions, so “only draws” is also too narrow.

An MQL5 EA uses the MetaTrader 5 environment; the term Expert Advisor also appears in MetaTrader 4 with its own language and interface. Other automated systems can use different order interfaces. See EAs in MT4 and MT5 and algorithmic trading first steps.

Buffer index zero need not be the last closed bar

Assume CopyBuffer succeeds with start_pos=1, count=3 into a plain array without AS_SERIES. Three closed-bar values are selected, with the oldest first in physical memory. In this specific configuration, the last closed value is at index 2.

Scroll sideways to see the full diagram

Physical order of three CopyBuffer valuesA plain array without AS_SERIES receives all three requested elements from shift 1. Memory contains shift 3=103,shift 2=101,shift 1=102. The last closed value is index 2, not index 0. A threshold greater than 102.5 passes for older 103 but not latest 102.PLAIN ARRAY: OLDEST FIRSTCopyBuffer: start_pos = 1, count = 3index 0shift 3103index 1shift 2101index 2shift 1102olderlast closedTest > 102.5: 103 passes, 102 does not.Shift 0 was not copied.

Fictional indicator values 103, 101, 102; copying returned exactly 3 elements with no partial result or error. The diagram uses a plain array without AS_SERIES. The 102.5 threshold checks data selection, not a trade signal. MQL5 — CopyBuffer describes start_pos counted from the current bar and the oldest copied element placed first in physical memory.

Reading 103 at index 0 versus 102 at index 2 can reverse the same check's result.

Record start_pos, the returned element count and target-array indexing in an EA test. Checking count without checking order can leave a bar-selection error. Do not apply index 2 universally to other array settings.

How an EA talks to the platform — the OnInit, OnTick, OnDeinit cycle

OnInit handles program initialisation. Initialisation is a lifecycle event, not a guarantee that a program is invoked only once throughout its use. Check resources and return a failure status when required setup cannot be completed.

OnTick handles NewTick events for the attached chart's symbol. If such an event is already queued or being processed, another is not added. An EA can also use other events and need not implement OnTick. Disabling AutoTrading prevents new trade requests but does not stop program operation or interrupt the current handler.

OnDeinit handles deinitialisation and its reason, including removal, shutdown or changes that trigger reinitialisation. Manage resources and preserved state explicitly. Other handlers such as OnTimer and OnTradeTransaction can be essential to the task; the life cycle is not limited to three callbacks. In a multi-symbol EA, a tick on the attached chart does not establish that every other symbol’s observations are current.

How an EA places orders — the CTrade class

OrderSend sends a request; true does not itself confirm that the market operation has filled. Inspect the response code and reconcile orders, deals and positions. OrderCheck is a precheck, not a guarantee of later execution. In a hypothetical failure test, the EA requests a 0.10-lot buy and loses certainty about the response. Retrying without reconciliation can create 0.20 lots if both requests fill; missing local confirmation does not prove the server did nothing.

OnTradeTransaction distinguishes an order’s removal from a deal added to history, and does not guarantee notification arrival priority. Assume no initial position and two confirmed buy fills, D1=0.04 and D2=0.06 lots. A defective counter that resets on ORDER_DELETE reads zero after D1, D2, ORDER_DELETE, but 0.10 after ORDER_DELETE, D1, D2. The confirmed buy sum is 0.10 in both orders. Order status and position exposure are different fields; a real ledger must also handle sells, reversals, history corrections and the account’s accounting mode.

CTrade provides methods such as Buy, Sell and PositionClose. A successful Buy method check does not always mean a successful trade operation: inspect ResultRetcode and ResultDeal. See slippage for execution-price differences.

The Strategy Tester, or how to check the EA has not just memorised history

MT5's Strategy Tester can run historical studies using generated ticks or broker-collected real ticks, depending on the selected mode and available data. Record provenance, timing, contract settings and costs with the results rather than assuming real ticks come from a universal MetaQuotes price source.

Selecting parameters on the same history later used for evaluation can overstate evidence. It does not mathematically guarantee a smooth curve or a live failure. Preserve an untouched evaluation period and document repeated research choices. See backtesting.

When an EA actually helps, and when it hurts

An EA can implement repeatable checks and monitor selected instruments. Two hundred trades a month, overnight operation or rapid decisions are possible design requirements, not evidence of a profitable edge.

Specify which information and event conditions the program uses, including any no-trade rules. Unusual releases or market conditions require testing and supervision, but do not automatically disqualify all automation. A marketplace chart or an unidentified forum survey is not a reliable estimate of future live performance.

Is it worth writing your own EA?

A small EA project can test whether precise rules are implemented correctly. Choose a learning budget from the required skills and project scope; three to six months or building rather than buying does not guarantee a superior outcome.

Unattended operation requires infrastructure, permissions and recovery procedures. The local AutoTrading button prevents EA trade requests but does not close positions or stop its calculations. A server-accepted ordinary stop can remain active after the local terminal closes, while an EA-only exit requires the program to run and reach the server. MetaQuotes Virtual Hosting is a separate migrated environment with automated trading allowed; the local button does not stop that remote instance. A Windows VPS is a different service. See VPS and latency.

Define acceptance checks for missing indicator data, restart, invalid volume steps, an uncertain request response and manual position changes. Restore current exposure before resuming rather than trusting an old local signal. With a netting account, strategies on the same symbol share its net position; a Magic Number does not create separate capital or margin.

The handle exists — is an indicator value ready?

Creating a handle does not establish that the indicator has calculated the required bar. BarsCalculated returns calculated data count, or −1 on error. Then check the actual CopyBuffer count, correct buffer and bar offset. Do not turn a failed read into zero: an RSI value of zero would describe an extreme state, not “information not ready”.

The handle exists — is an indicator value ready?

The handle exists — is an indicator value ready?Four separate checks: handle, calculated data, copied count and valid value.Handlenot INVALIDCalculated datarequired barCopyBufferexpected countValuevalid, non-empty
Readiness requires every check to pass.

Our model requires one value: (A) invalid handle — no reading; (B) handle exists but 0 values copied — wait; (C) 1 copied value is EMPTY_VALUE — no usable signal; (D) 1 valid value of 45 copied — the rule can now be evaluated. The 45 is a fictional reading, not an investment signal.

EMPTY_VALUE defaults to DBL_MAX, a finite number; a finiteness check alone is insufficient. Custom indicators may define another empty marker. Check their contract rather than rejecting every zero. Missing history, an empty marker and a valid number are different states.

Exercise: a handle and one copied value exist, but the value is EMPTY_VALUE. What next?

Do not evaluate the strategy threshold. Check the buffer, bar and empty marker, record unavailable data and retry on the next appropriate event. Do not invent a zero observation.

API data requires a separate availability check: replaying information in an offline test. A chart-dependent rule has different limitations: visual testing differences.

What to do tomorrow

  1. Download MetaTrader 5 from your broker's site, open a demo account, and go to the Strategy Tester tab. Load one of the built-in sample EAs (Moving Average or MACD Sample) on EUR/USD H1, run a single pass, and read the resulting report carefully to see what the basic metrics — equity curve, drawdown, profit factor — look like in practice.
  2. Open the official MQL5 documentation at mql5.com/en/docs and read only three chapters: OnInit, OnTick, and the CTrade class. Do not try to write anything yet — the goal is to see how the documentation is organised and where to find worked examples once you need them.
  3. Write input, entry, exit, sizing and no-trade conditions. Mark any discretionary decision explicitly; contextual rules may be formalised if their inputs and conditions are specified. See the setup checklist.
  4. Plan a small learning project with explicit acceptance checks for data access, event processing and order responses. Its scope and duration depend on the required functions and skills.
  5. Check the operating workflow on demo before considering live exposure. A one-month period is illustrative, and demo execution may differ from live execution. The tester can emulate delays, but simulated delay is not a measurement of all future real fills.