Statistics & regression

13 functions

AVEDEV(X, N)

Mean absolute deviation over N bars.

X(series)
The series to measure.
N(integer)
Window length in bars.
// CCI, written out in full
TYP := (HIGH + LOW + CLOSE) / 3;
CCI: (TYP - MA(TYP, 14)) / (0.015 * AVEDEV(TYP, 14)), COLORYELLOW;

// unlike STD, outliers do not get squared, so AVEDEV
// reacts more gently to a single wild bar
DEVSQ(X, N)

Sum of squared deviations from the mean.

X(series)
The series to measure.
N(integer)
Window length in bars.
// the numerator behind variance — divide by N for VARP,
// by N-1 for VAR
SS: DEVSQ(CLOSE, 20);
MYVARP: SS / 20;
STD(X, N)

Sample standard deviation over N bars — the one Bollinger Bands use.

X(series)
The series to measure.
N(integer)
Window length in bars.
// Bollinger Bands
MID:   MA(CLOSE, 20);
UPPER: MID + 2 * STD(CLOSE, 20), COLORYELLOW;
LOWER: MID - 2 * STD(CLOSE, 20), COLORYELLOW;

// bandwidth — a squeeze is a low reading here
WIDTH: (UPPER - LOWER) / MID * 100;
SQUEEZE := WIDTH < LLV(WIDTH, 120) * 1.1;
STICKLINE(SQUEEZE, HIGH, LOW, 8, 1), COLORLIBLUE;
STDP(X, N)

Population standard deviation.

X(series)
The series to measure.
N(integer)
Window length in bars.
// divides by N rather than N-1 — slightly smaller than STD,
// and the gap only matters at short lengths
SAMPLE: STD(CLOSE, 10),  COLORYELLOW;
POP:    STDP(CLOSE, 10), COLORGRAY;
STDDEV(X, N)

Standard error — standard deviation divided by √N.

X(series)
The series to measure.
N(integer)
Window length in bars.
// how precise the moving average itself is —
// a confidence band around the mean, not around price
MID: MA(CLOSE, 20);
HI:  MID + 2 * STDDEV(CLOSE, 20), COLORGRAY, DOTLINE;
LO:  MID - 2 * STDDEV(CLOSE, 20), COLORGRAY, DOTLINE;
VAR(X, N)

Sample variance.

X(series)
The series to measure.
N(integer)
Window length in bars.
// variance is the square of STD — same information,
// different scale; useful when you need to add variances up
V: VAR(CLOSE / REF(CLOSE, 1) - 1, 20);
SAME: POW(STD(CLOSE / REF(CLOSE, 1) - 1, 20), 2);
VARP(X, N)

Population variance.

X(series)
The series to measure.
N(integer)
Window length in bars.
// treats the window as the whole population, dividing by N
VP: VARP(CLOSE, 20);
// equals DEVSQ(CLOSE, 20) / 20
SAME: DEVSQ(CLOSE, 20) / 20;
COVAR(X, Y, N)

Covariance of X and Y over N bars.

X(series)
First series.
Y(series)
Second series.
N(integer)
Window length in bars.
// do price and volume move together? covariance keeps the
// units, so its size is not comparable across symbols —
// divide by the two standard deviations to get RELATE
CV: COVAR(CLOSE, VOL, 20);
R:  CV / (STD(CLOSE, 20) * STD(VOL, 20));
RELATE(X, Y, N)

Correlation coefficient of X and Y over N bars.

X(series)
First series.
Y(series)
Second series.
N(integer)
Window length in bars.
// bounded to -1…1, so it reads the same on any symbol
R: RELATE(CLOSE, VOL, 20), COLORYELLOW;

// price rising on falling volume — a classic divergence filter
WEAK := R < -0.5 AND CLOSE > MA(CLOSE, 20);
DRAWICON(WEAK, HIGH, 97);
FORCAST(X, N)

Linear regression value over the last N bars.

X(series)
The series to fit.
N(integer)
Number of bars in the regression window.
// the regression line itself, plus a channel built from
// how far price typically strays from it
REG: FORCAST(CLOSE, 40), COLORYELLOW;
DEV := STD(CLOSE - REG, 40);
UP: REG + 2 * DEV, COLORGRAY, DOTLINE;
DN: REG - 2 * DEV, COLORGRAY, DOTLINE;
SLOPE(X, N)

Slope of the linear regression over the last N bars.

X(series)
The series to fit.
N(integer)
Number of bars in the regression window.
// price change per bar implied by the trend line
SLP: SLOPE(CLOSE, 20);

// normalise it so the reading is comparable across symbols
NORM: SLP / CLOSE * 100, COLORSTICK;
UPTREND := NORM > 0.1;
BETA(N)legacy feed

Beta of the symbol against the market index over N bars.

N(integer)
Window length in bars.
// needs an A-share style feed for the index leg —
// on the current data source this draws nothing
B: BETA(60), COLORYELLOW;
HIGHBETA := B > 1.2;
BETA2(X, Y, N)

Beta of series X against series Y over N bars.

X(series)
The series being explained.
Y(series)
The benchmark series.
N(integer)
Window length in bars.
// unlike BETA, both legs are yours — pass in any benchmark
// that the current feed can supply
BENCH := COVER_C('WEEK');
B: BETA2(CLOSE, BENCH, 60), COLORYELLOW;