Skip to content

Algorithm SDK

onIntervalClose

Runs when each bar (candle) closes on your session’s timeframe. Most strategies trade here, once per bar, rather than on every tick.

function onIntervalClose(): void

A bar closes when the first tick of the next bar arrives, so onIntervalClose runs only for bars that had ticks. During it:

  • TIME is the close time of the bar.
  • OPEN, HIGH, LOW, CLOSE and PRICE describe the bar that just closed.
  • BID and ASK are the prices of the tick that opened the new bar, which is what a market order now fills near.
  • Indicators have been updated with the closed bar.

Assign a function at the top level of your script to handle the bars of another timeframe, another instrument, or both:

H1.onIntervalClose = function () {
log("Hourly close", H1.CLOSE);
};
INSTRUMENTS["EUR_USD:OANDA"].onIntervalClose = function () {
log("EUR/USD bar closed", INSTRUMENTS["EUR_USD:OANDA"].CLOSE);
};
INSTRUMENTS["EUR_USD:OANDA"].M30.onIntervalClose = function () {
log("EUR/USD 30-minute high", INSTRUMENTS["EUR_USD:OANDA"].M30.HIGH);
};

An instrument can have a shorter name, declared at the top level: const eurusd = INSTRUMENTS["EUR_USD:OANDA"]; and then eurusd.M30.onIntervalClose = function () { … };. Assign a function () {} written in place, not the name of a function: H1.onIntervalClose = checkHourlyRange; is refused when the run starts. To reuse a function, call it from the handler:

function checkHourlyRange() {
const range = H1.HIGH - H1.LOW;
log("Hourly range", range);
}
H1.onIntervalClose = function () {
checkHourlyRange();
};

As for onTick: the error is logged, a backtest stops, and a live session stops after three errors within 60 seconds.

function onIntervalClose() {
if (OPEN_POSITIONS_COUNT === 0 && sma(20) > sma(50)) {
openPosition("BUY", { riskPercentage: 1, stopLossPips: 25, takeProfitPips: 50 });
}
}