Your First EA: MA Crossover
Line by line through the platform’s example EA — including the warm-up bug.
Written and reviewed by the Fundezy team · how we produce this
The platform ships a complete example: a Simple MA Crossover EA. It buys when a fast moving average crosses above a slow one, and sells on the opposite cross — the purest trend-following starter. Let's read it the way a reviewer would.
The logic in words
- Each tick, read the fast MA (period 10) and slow MA (period 30) on the current bar (shift 0) and the previous bar (shift 1).
- Bullish cross: fast was ≤ slow on the previous bar, and is > slow now → buy.
- Bearish cross: the mirror condition → sell.
- Trade one position at a time, fixed lot size from an input.
The code that matters
input int FastMAPeriod = 10;
input int SlowMAPeriod = 30;
input double LotSize = 0.01;
void OnTick()
{
string symbol = Symbol();
int tf = Period();
double fastMA_current = iMA(symbol, tf, FastMAPeriod, 0, MODE_SMA, PRICE_CLOSE);
double fastMA_prev = iMA(symbol, tf, FastMAPeriod, 1, MODE_SMA, PRICE_CLOSE);
double slowMA_current = iMA(symbol, tf, SlowMAPeriod, 0, MODE_SMA, PRICE_CLOSE);
double slowMA_prev = iMA(symbol, tf, SlowMAPeriod, 1, MODE_SMA, PRICE_CLOSE);
// Guard: indicators return 0 until enough bars exist
if (fastMA_current <= 0 || slowMA_current <= 0)
return;
bool bullishCross = (fastMA_prev <= slowMA_prev) && (fastMA_current > slowMA_current);
bool bearishCross = (fastMA_prev >= slowMA_prev) && (fastMA_current < slowMA_current);
if (bullishCross) OrderSend(symbol, OP_BUY, LotSize, Ask, 10, 0, 0, "MA cross up");
if (bearishCross) OrderSend(symbol, OP_SELL, LotSize, Bid, 10, 0, 0, "MA cross down");
}
The bug that teaches the most
That innocent-looking guard line — if (fastMA_current <= 0 || slowMA_current <= 0) return; — is the difference between a valid backtest and garbage. Here's why it exists on this platform:
Indicators return 0 until their period's worth of bars exists. An SMA(30) can't be computed until 30 bars have passed. On bar one, iMA returns 0. Without the guard, fastMA_prev (0) ≤ slowMA_prev (0) is true, and any positive current reading looks like a bullish cross — the EA fires a phantom trade on the very first bars. This exact bug was found and fixed in the platform's own test suite.
The lesson generalizes: always check indicator validity during warm-up. Every indicator here has this behavior (RSI returns a neutral 50 during warm-up — same problem, sneakier).
Weaknesses you should already see
You've done Course 03 — spot the flaws:
- No stop loss, no take profit (zeros passed to OrderSend). A cross-strategy without stops is one trend away from margin trouble.
- Fixed lot size — the 1% rule should size orders from
AccountEquity()and stop distance. - Whipsaw exposure — MAs lag; choppy ranges generate serial false crosses.
Each weakness is a hypothesis: "adding a stop at structure improves net P/L." The Strategy Tester is where hypotheses go to be confirmed or destroyed — next lesson.
By the numbers
The bug every first EA hits: iMA() returns 0 — not an error — until its period of bars exists, so an SMA(30) signal computed on the chart's first bar is undefined, not zero. The lesson's example uses periods 10/30 plus a warm-up guard that simply refuses to trade until the slow average has data — two lines that eliminate the entire class of bug.
Practice in the simulator
Open the Strategy Tester with the example EA — apply what you just read with simulated money.
Check your understanding
4 questions · answer all, then submit.