feature
Remembering values across bars
Scripts often need memory across bars — an EMA, a session open, a “was above yesterday” flag. That memory belongs in ctx.accum, not in a module-level let.
If you skip this, lint fails and your values reset or behave unpredictably. Use this page whenever a calculation depends on what happened on earlier bars.
Signature
// Indicator
ctx.accum<T>(id: string, init: T, update: (prev: T) => T): T
// Definition — init may be a value or a thunk
ctx.accum<T>(id: string, init: T | (() => T), update: (prev: T) => T): TExample
function onBar(ctx) {
const k = 2 / (ctx.params.length + 1);
const ema = ctx.accum("ema", null, (prev) =>
prev == null ? ctx.close : prev + k * (ctx.close - prev)
);
ctx.plot("ema", ema);
}Rules
Stable string
idper accumulatorReturn the next value from
update(do not rely on mutating shared objects unless you understand the runtime)Studies: no
ctx.accum— usectx.collectacross events instead
Agent note
Inventing let ema = … at module scope is the most common agent mistake on indicators and definitions.
