Indicator Computation
Understanding how indicators are computed helps you write efficient strategies.
Host-Side Computation
Unlike traditional backtesting where you compute indicators in your strategy code, QSL indicators are computed by the engine before your onBar() runs.
1. define(ctx) runs - parameters collected 2. init(ctx) runs - indicator declarations collected 3. ENGINE COMPUTES ALL INDICATORS (host-side, fast) 4. onBar(ctx, i) runs - indicators already available
Why This Matters
Performance
Computing a 200-period EMA on 10,000 bars requires 10,000 calculations. If done in JavaScript for every bar, that's 100 million operations.
With host-side computation:
- Computed once in optimized native code
- Results passed to your strategy as arrays
- 10x-100x faster than in-strategy computation
Consistency
All strategies use the same indicator implementations:
- No bugs in custom indicator code
- Results match across strategies
- Platform-verified accuracy
Declaration in init()
function init(ctx) { // These are declarations, not computations ctx.indicator('ema', 'EMA', { period: ctx.p.period, source: 'close' }); ctx.indicator('rsi', 'RSI', { period: 14 }); ctx.indicator('macd', 'MACD', { fastPeriod: 12, slowPeriod: 26, signalPeriod: 9 }); }
Access in onBar()
By the time onBar() runs, all indicator values are pre-computed:
function onBar(ctx, i) { // These are array lookups, not calculations const ema = ctx.ind.ema[i]; const rsi = ctx.ind.rsi[i]; const macdLine = ctx.ind.macd.macd[i]; const macdSignal = ctx.ind.macd.signal[i]; }
Warm-up Period
Indicators need historical data before producing valid values:
| Indicator | Warm-up |
|---|---|
| SMA(20) | 20 bars |
| EMA(20) | ~20 bars |
| RSI(14) | 15 bars |
| MACD(12,26,9) | 35 bars |
During warm-up, values are NaN:
function onBar(ctx, i) { // Always check for NaN if (q.isNaN(ctx.ind.ema[i])) return; // Now safe to use }
Don't Compute Manually
// WRONG - Computing in onBar (slow) function onBar(ctx, i) { let sum = 0; for (let j = i - 20; j <= i; j++) { sum += ctx.series.close[j]; } const sma = sum / 20; } // RIGHT - Declare in init (fast) function init(ctx) { ctx.indicator('sma', 'SMA', { period: 20 }); } function onBar(ctx, i) { const sma = ctx.ind.sma[i]; // Pre-computed }
Related
- init() — Declaring indicators
- Available Indicators — Full indicator list
Related
engineindicatorscomputationperformanceqsl