feature
Session OR break
Builds a session opening range from the first N bars after session open, then emits once when price breaks the high (or low) after the range is locked.
What it defines
Events or_break_up / or_break_dn with the OR high/low and break price — one break direction per session via oncePer.
Key decisions
Piece | Why it matters |
|---|---|
| Definition session object ( |
OR state in | Remembers high/low/bar count across bars; resets on |
Emit only after range locked | Avoid firing during the building window. |
Separate event ids + | One up and one down break max per session, no hand-rolled dedupe. |
Full script
meta({
name: "OR break",
kind: "flow",
slug: "or-break",
shortName: "ORBreak",
});
events.declare({
id: "or_break_up",
intent: "Close breaks above session opening range",
payload: {
orHigh: { type: "number", description: "Opening range high" },
orLow: { type: "number", description: "Opening range low" },
close: { type: "number", description: "Break close" },
sessionKey: { type: "string", description: "Session key" },
},
paint: "pin",
oncePer: { keys: ["session"] },
});
events.declare({
id: "or_break_dn",
intent: "Close breaks below session opening range",
payload: {
orHigh: { type: "number", description: "Opening range high" },
orLow: { type: "number", description: "Opening range low" },
close: { type: "number", description: "Break close" },
sessionKey: { type: "string", description: "Session key" },
},
paint: "pin",
oncePer: { keys: ["session"] },
});
outputs.declare({ id: "or_high", kind: "line", name: "OR high", color: "#26a69a" });
outputs.declare({ id: "or_low", kind: "line", name: "OR low", color: "#ef5350" });
const OR_BARS = 5;
export function onBar(ctx) {
const s = ctx.session({});
const st = ctx.accum("or", null, (prev) => {
if (s.didOpen || prev == null) {
return {
key: s.key,
bars: 1,
high: ctx.high,
low: ctx.low,
locked: false,
};
}
if (prev.locked) return prev;
const bars = prev.bars + 1;
const high = Math.max(prev.high, ctx.high);
const low = Math.min(prev.low, ctx.low);
return {
key: s.key,
bars,
high,
low,
locked: bars >= OR_BARS,
};
});
if (!st.locked) return;
ctx.plot("or_high", st.high);
ctx.plot("or_low", st.low);
const base = {
orHigh: st.high,
orLow: st.low,
close: ctx.close,
sessionKey: st.key,
};
if (ctx.close > st.high) {
ctx.emit("or_break_up", base, {
label: "OR break ↑",
subtitle: `H ${st.high.toFixed(2)}`,
price: ctx.close,
timeStart: ctx.time,
});
} else if (ctx.close < st.low) {
ctx.emit("or_break_dn", base, {
label: "OR break ↓",
subtitle: `L ${st.low.toFixed(2)}`,
price: ctx.close,
timeStart: ctx.time,
});
}
}Tune SessionOpts in IntelliSense for your market (exchange RTH vs named London/NY sessions). See Sessions.
