Skip to content
Open RaamTrade

LinearRegression — Linear Regression

The least-squares fit of price on bar index over the window, delivered as three outputs: the fitted endpoint (.fitted), the slope per bar (.slope), and the fit quality (.r2).

Signature

LinearRegression(period, on=<source>)
Argument Type Required Notes
period int Param or literal Yes Regression window. Default 14, bounds 2–400.
on= symbol, OHLCV field, or indicator No Source. Defaults to the trade symbol’s close.

Formula

With bar index $i = 0 \ldots n-1$ (oldest to newest) over the window:

$$ \text{slope} = \frac{n\sum iC_i - \sum i \sum C_i}{n\sum i^2 - (\sum i)^2}, \quad \text{fitted} = \text{intercept} + \text{slope},(n-1), \quad r^2 = 1 - \frac{\sum (C_i - \hat{C}_i)^2}{\sum (C_i - \bar{C})^2} $$

fitted is the regression value at the newest bar — what LSMA plots.

Warmup

period bars. Until then: fitted = close, slope = 0, r2 = 1. On a perfectly flat window r2 is 1 (a flat line fits perfectly).

Reading the value

lr.fitted
lr.slope
lr.r2
lr.slope > 0 and lr.r2 > 0.8

Multi-value: it cannot be chained onto (SMA(5, on=lr)) or crossed. Use LinearRegressionSlope when you need a single-value slope to smooth or cross.

Example

class QualityTrend(Strategy):
"""Trend entry only when the regression is steep and clean."""
period = Param(20, min=2, max=400)
trade = Symbol()
sizing = FixedCapital()
def execute(self):
lr = LinearRegression(self.period, on=self.trade)
if lr.slope > 0 and lr.r2 > 0.8 and self.trade.is_flat:
self.buy(self.trade, reason=f"slope {lr.slope:.3f} r2 {lr.r2:.2f}")
if lr.slope < 0 and self.trade.is_long:
self.sell(self.trade, self.trade.position, reason="Slope flipped")

Notes

  • Ordinary least squares; the closed-form sums use 0-based indices.
  • Naming: the catalog sketched the outputs as .value/.slope/.r2, but value is a reserved output key in RaamCode (RC2_IND_RESERVED_OUTPUT_KEY), so the endpoint ships as .fitted.
  • Proven by an assert-via-trade run on SPY daily (all three outputs matched a strategy-side OLS reference on every bar; zero alarm trades).