mirror of
https://github.com/mihakralj/QuanTAlib.git
synced 2026-07-27 17:27:43 +00:00
69 lines
2.9 KiB
Plaintext
69 lines
2.9 KiB
Plaintext
// Licensed under the Apache License, Version 2.0
|
|
// © mihakralj
|
|
//@version=6
|
|
indicator("Integral of Linear Regression Slope (ILRS)", "ILRS", overlay=true)
|
|
|
|
//@function Computes the Integral of Linear Regression Slope — cumulative sum of the
|
|
// least-squares slope computed over a rolling window. Tracks accumulated
|
|
// trend direction as a price-overlay smoothing filter.
|
|
//@param source Series to analyze
|
|
//@param period Lookback window for slope calculation (>= 2)
|
|
//@returns Cumulative integral of the rolling linear regression slope
|
|
//@reference John Ehlers, "Rocket Science for Traders" (Wiley, 2001).
|
|
//@reference Concept: ILRS is the discrete integral (running sum) of the LinReg slope,
|
|
// producing a smoother trend follower than LSMA. Equivalent to filtering
|
|
// the first derivative and reconstructing via integration.
|
|
//@optimized O(period) per bar for slope via circular buffer accumulation
|
|
ilrs(series float source, simple int period) =>
|
|
if period < 2
|
|
runtime.error("Period must be at least 2")
|
|
|
|
float price = nz(source)
|
|
|
|
// --- Circular buffer for rolling window ---
|
|
var array<float> buffer = array.new_float(period, na)
|
|
var int head = 0
|
|
array.set(buffer, head, price)
|
|
head := (head + 1) % period
|
|
|
|
// --- Running integral state ---
|
|
var float integral = na
|
|
|
|
int count = math.min(bar_index + 1, period)
|
|
if count < 2
|
|
integral := price
|
|
integral
|
|
else
|
|
// --- Compute linear regression slope over the buffer ---
|
|
// x-indices: 0, 1, ..., n-1 (oldest to newest)
|
|
// Analytical x-sums: ΣX = n(n-1)/2, ΣX² = n(n-1)(2n-1)/6
|
|
float n = count
|
|
float sumX = 0.5 * (n - 1) * n
|
|
float sumX2 = (n - 1) * n * (2 * n - 1) / 6.0
|
|
|
|
// Accumulate y-sums from circular buffer
|
|
int start = count < period ? 0 : head
|
|
float sumY = 0.0
|
|
float sumXY = 0.0
|
|
for i = 0 to int(n) - 1
|
|
int idx = (start + i) % period
|
|
float val = nz(array.get(buffer, idx))
|
|
sumY += val
|
|
sumXY += i * val
|
|
|
|
float denomX = n * sumX2 - sumX * sumX
|
|
float slope = denomX != 0 ? (n * sumXY - sumX * sumY) / denomX : 0.0
|
|
|
|
// --- Integrate: ILRS = ILRS[1] + slope ---
|
|
if na(integral)
|
|
integral := price
|
|
integral := integral + slope
|
|
integral
|
|
|
|
// ── Inputs ──────────────────────────────────────────────────────────────
|
|
src = input.source(close, "Source")
|
|
per = input.int(14, "Period", minval=2)
|
|
|
|
// ── Plot ────────────────────────────────────────────────────────────────
|
|
plot(ilrs(src, per), "ILRS", color.new(color.yellow, 0), 2)
|