Scalping EA in MetaTrader 5: Logic, Risk, and a Simple Example
A scalping EA in MetaTrader 5 is an Expert Advisor that aims for many small profits on short timeframes (typically M1 or M5), holding positions for minutes rather than hours. Because targets are small, spread, slippage, and tick-level execution matter a lot — so your EA should filter by spread, use tight risk rules, and be backtested with Every tick in the Strategy Tester. This guide explains how scalping EAs work, how to set entry/exit and risk, and gives a simple M1 moving-average crossover example in MQL5 with references to official documentation.
Quick answer: A practical MT5 scalping setup is M1/M5 timeframe, spread filter enabled, one-position-at-a-time logic, and Every tick testing before Demo/Live.
Before you run a scalping EA, verify:
- Spread threshold is realistic for your symbol and broker
- Tick mode is set to Every tick (or real ticks)
- Stop loss / position sizing follows strict risk limits
- You test in Strategy Tester and then Demo before Live
Related guides: MQL5 Programming Reference · Advanced EA: Multi-Timeframe & Filters · Backtest EA in MT5 Strategy Tester · Build EA Without Coding
What is a Scalping EA?
Scalping is a style of trading that tries to capture small price moves many times per day. A scalping Expert Advisor automates this: it opens and closes positions quickly, often on M1 or M5. In MQL5, the main event for reacting to new prices is OnTick(): "The function is called in EAs when the NewTick event occurs to handle a new quote." So scalping EAs typically put their trading logic inside OnTick(), checking conditions on every new tick or on each new bar (e.g. using a "new bar" check to avoid multiple entries per bar).
Characteristics: Timeframes and Spread
| Aspect | Typical choice for scalping | Why |
|---|---|---|
| Timeframe | M1, M5 | More bars and signals; decisions based on short-term price action. |
| Spread | Low, filtered in code | Spread eats into small targets; use SymbolInfoInteger(Symbol(), SYMBOL_SPREAD) or SymbolInfoTick to get current bid/ask and skip trading when spread is too high. |
| Symbols | Major forex (e.g. EURUSD), sometimes indices | Usually better liquidity and lower spread during main sessions. |
MQL5 recommends using SymbolInfoTick() when you need the latest prices in one call: "It may well be that not a single quote has appeared yet since the terminal is connected... In most cases, it is enough to use SymbolInfoTick() function allowing a user to receive the values of Ask, Bid, Last, Volume and the time of the last tick's arrival during a single call." For scalping, that means reliable, up-to-date bid/ask for entries and spread checks.
Entry, Exit, and Risk
- Entry: Often based on fast signals: crossovers, breakouts, or short-term momentum. Many scalping EAs only allow one position at a time and wait for the next bar or a clear exit before re-entering.
- Exit: Fixed target (take profit) and stop loss in pips/points; sometimes time-based exit (close after N bars or N seconds).
- Risk: Use small lot sizes and strict stop loss. Rely on EA risk management principles: limit risk per trade and total exposure. Because scalping trades frequently, small edges can be wiped out by spread and slippage if not controlled.
Strategy Tester: Use Every Tick
When backtesting a scalping EA, tick generation mode is critical. According to MetaTrader 5: "Every tick" is used to ensure the best testing accuracy. Simulated conditions are the most realistic in this mode. For scalping, Every tick (or Every tick based on real ticks when available) is the appropriate choice; 1 minute OHLC or Open prices only can give misleading fill prices and equity curves. For a full walkthrough, see Backtest Your EA in the Strategy Tester.
Example: Simple M1 MA Crossover EA
Below is a minimal MQL5 scalping-style EA: it uses M1, a fast/slow moving-average crossover for signals, a spread filter, and one position at a time. Logic runs on new bar to avoid multiple entries per bar.
//+------------------------------------------------------------------+
//| Simple M1 MA crossover scalping-style EA (educational example) |
//+------------------------------------------------------------------+
#property copyright "Example"
#property version "1.00"
#property strict
input int FastMA = 8;
input int SlowMA = 21;
input int MaxSpreadPoints = 20; // max spread in points to allow entry
input double LotSize = 0.1;
input int Slippage = 10;
input ulong Magic = 12345;
int g_fastHandle, g_slowHandle;
int OnInit() {
g_fastHandle = iMA(_Symbol, PERIOD_M1, FastMA, 0, MODE_EMA, PRICE_CLOSE);
g_slowHandle = iMA(_Symbol, PERIOD_M1, SlowMA, 0, MODE_EMA, PRICE_CLOSE);
if (g_fastHandle == INVALID_HANDLE || g_slowHandle == INVALID_HANDLE) {
Print("Failed to create MA handles");
return INIT_FAILED;
}
return INIT_SUCCEEDED;
}
void OnDeinit(const int reason) {
if (g_fastHandle != INVALID_HANDLE) IndicatorRelease(g_fastHandle);
if (g_slowHandle != INVALID_HANDLE) IndicatorRelease(g_slowHandle);
}
bool isNewBar() {
static datetime lastBar = 0;
datetime curBar = iTime(_Symbol, PERIOD_M1, 0);
if (curBar != lastBar) { lastBar = curBar; return true; }
return false;
}
void OnTick() {
if (!isNewBar()) return;
// Spread filter (official: SymbolInfoInteger with SYMBOL_SPREAD)
long spreadPoints = SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
if (spreadPoints > MaxSpreadPoints) return;
if (PositionsTotal() > 0) return; // one position at a time
double fast[2], slow[2];
if (CopyBuffer(g_fastHandle, 0, 1, 2, fast) != 2) return;
if (CopyBuffer(g_slowHandle, 0, 1, 2, slow) != 2) return;
bool crossUp = (fast[0] > slow[0] && fast[1] <= slow[1]);
bool crossDown = (fast[0] < slow[0] && fast[1] >= slow[1]);
MqlTradeRequest req = {};
MqlTradeResult res = {};
req.symbol = _Symbol;
req.volume = LotSize;
req.deviation = Slippage;
req.magic = Magic;
req.action = TRADE_ACTION_DEAL;
if (crossUp) {
req.type = ORDER_TYPE_BUY;
req.price = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
OrderSend(req, res);
} else if (crossDown) {
req.type = ORDER_TYPE_SELL;
req.price = SymbolInfoDouble(_Symbol, SYMBOL_BID);
OrderSend(req, res);
}
}
Notes: This is a simplified example. In production you would add take profit, stop loss, and possibly multi-timeframe or session filters. Spread is read with SymbolInfoInteger(_Symbol, SYMBOL_SPREAD) as in the MQL5 documentation.
Practical Tips
- Broker and symbol: Choose a broker with low, stable spread on the pairs you scalp. Test in Strategy Tester with Every tick.
- Sessions: Scalping often performs better during high-liquidity sessions (e.g. London, New York). You can add time or session filters to your EA.
- VPS: For 24/7 execution without gaps, consider running the EA on a VPS close to the broker server.
- Gold (XAUUSD): If you scalp gold, be aware of higher volatility and spread; see EA for Gold (XAUUSD) for symbol-specific considerations.
Next Steps
- Build your first EA if you are new to MQL5 structure and events.
- Backtest your EA with Every tick and forward testing before going live.
- Deploy and maintain your EA on demo then real accounts with proper monitoring.
References: MQL5 OnTick, SymbolInfoInteger, SymbolInfoTick, MetaTrader 5 Strategy Tester.