Build a moving-average crossover
Your first algorithm, from an empty editor to a backtest, in about twenty minutes.
A crossover buys when a fast moving average rises above a slow one, and sells when it falls below. It is simple, easy to check on a chart, and a good base to build on.
1. Create the algorithm
Section titled “1. Create the algorithm”Do this: Open Algorithms, type a name such as “SMA crossover”, and select New.
You should see: The editor, on an unsaved version 1.
2. Declare the settings you will want to change
Section titled “2. Declare the settings you will want to change”Do this: Replace the editor’s contents with:
const externals = [ { name: "fast", defaultValue: 5 }, { name: "slow", defaultValue: 20 }, { name: "stopPips", defaultValue: 20 }, { name: "targetPips", defaultValue: 40 },];
if (fast >= slow) { error("fast must be smaller than slow");}
let wasAbove = sma(fast) > sma(slow);Each external becomes a number you can use by name, and you can change it for each backtest or session without editing code. error() stops the run with your message if the settings make no sense.
Code at the top level runs once, when the first price arrives, so wasAbove starts as whether the fast average is above the slow one then, and a variable declared there keeps its value between bars. Algorithm concepts explains more.
3. Trade when the averages cross
Section titled “3. Trade when the averages cross”Do this: Add below it:
function onIntervalClose() { const isAbove = sma(fast) > sma(slow);
if (isAbove !== wasAbove && OPEN_POSITIONS_COUNT === 0) { openPosition(isAbove ? "BUY" : "SELL", { quantity: 10000, stopLossPips: stopPips, takeProfitPips: targetPips, }); }
wasAbove = isAbove; plot("Fast SMA", sma(fast)); plot("Slow SMA", sma(slow));}onIntervalClose runs once at the end of each bar, so a cross is judged on closed bars rather than on every flicker of the price. Only one position is open at a time, and every position has a stop and a target.
4. Save and backtest
Section titled “4. Save and backtest”Do this: Press Ctrl+S and add a short commit message. Open the Backtest tab and select New Backtest. Pick EUR/USD at 1 hour on Minute data, over the last six months, and select OK.
You should see: The run complete in a minute or two, with your two averages drawn over the price and a marker for each position.
5. Check it did what you meant
Section titled “5. Check it did what you meant”Open a few positions on the chart. Each should open on the bar after the averages cross, and close at its stop or target. If not, see Debug an algorithm.
Common questions
Section titled “Common questions”Why onIntervalClose and not onTick? On every tick the averages can cross and uncross many times inside one bar. Waiting for the close trades once per real cross.
Should I use these settings? No. They are a starting point. Read Optimize without overfitting before you tune them.