Skip to main content

Multi-timeframe

request.timeframe gives you a higher timeframe of the same symbol, built from the chart's own bars:

import { request, param, ta, src, plot } from "@coinray/strategy";

const tf = param.timeframe("Trend timeframe", "240");
const htf = request.timeframe(tf, 60); // 60 = higher-timeframe bars of history you need

export function onBar(): void {
const trend = ta.ema(htf.close, 50); // an EMA over 4h bars
plot("trend", trend[1]);
const uptrend = src.close[0] > trend[1];
}

htf has the same members as src: open high low close volume hl2 hlc3 ohlc4 hlcc4 time.

[0] repaints, [1] does not​

Higher-timeframe series are indexed in higher-timeframe bars:

  • htf.close[0] is the developing bar. It changes with every chart bar until the higher-timeframe bar closes, the same as Pine's default on realtime bars.
  • htf.close[1] is the last closed bar. It never changes. Use it for signals.

An indicator over a higher-timeframe series runs on that timeframe: ta.ema(htf.close, 50)[1] is the EMA as of the last closed 4h bar.

Indicators without a source​

ta.atr, ta.dmi and the other indicators that read high, low and close run on the chart. To run them on a higher timeframe, call them on the context:

const atr4h = htf.atr(14); // ATR over 4h bars
const dmi4h = htf.dmi(14, 14); // dmi4h.adx[1]

Available: atr tr cci wpr stochK sar dmi supertrend accdist iii.

Your own values on a higher timeframe​

htf.series() (top level) is a user series indexed in higher-timeframe bars. Write it every chart bar; the value written on the last chart bar of a 4h bar becomes that bar's value:

const range4h = htf.series();

export function onBar(): void {
range4h[0] = htf.high[0] - htf.low[0];
const avgRange = ta.sma(range4h, 10); // over 4h bars
plot("avg 4h range", avgRange[1]);
}

Other symbols​

request.security(symbol, tf, bars) is the same thing for another symbol on the chart's exchange:

const eth = request.security("ETH/USDT", ""); // ETH at the chart timeframe
const eth4h = request.security("ETHUSDT", "240"); // ETH on 4h

export function onBar(): void {
const ratio = src.close[0] / eth.close[0];
plot("eth 4h atr", eth4h.atr(14)[1]);
}
  • "" as the timeframe is the chart timeframe. "BINANCE:ETHUSDT", "ETHUSDT", "ETH/USDT" and "USDT_ETH" all name the same market.
  • On each chart bar the other symbol's bars are those that opened at or before that bar, never later.
  • A bar the other symbol does not have (a gap, or before it listed) repeats its last close with zero volume.

Rules​

  • Call request.timeframe / request.security at top level. At most 5 per script, at most 3 other symbols, all on the chart's exchange.
  • The timeframe must be an exact multiple of the chart timeframe, at most 500 times larger, and at most 1 day. Otherwise the script stops with an error on its first bar. Weekly and monthly are not supported.
  • ta.atr, ta.tr, ta.dmi, ta.supertrend, ta.sar, ta.cci, ta.wpr, ta.stochK run on the chart timeframe; use htf.atr(...) and friends for a higher timeframe.
  • There is no lookahead_on: a script can never read a higher-timeframe bar before it closes.
  • param.timeframe(name, default, choices) adds a dropdown whose value you can pass straight to request.timeframe.

The bars argument sets how much history is loaded, in higher-timeframe bars. Set it to at least the longest lookback you use on that timeframe.