Skip to main content
Build signals the way a quant does, inside the script: rolling statistics, models that learn one bar at a time, principal components, and matrices. Each model is an instance, like an indicator: create it at the top, update it on every bar, and it rolls back with the forming bar.

Statistics

stats.* are rolling statistics that match pandas, so a number checked in a notebook is the number on the chart. Variance divides by n − 1, as pandas does; ta.stdev keeps TradingView’s n.
zscore, corr, cov, beta, skew, kurt, quantile, median and autocorr work over the last length values. ewmVar, ewmCov and ewmCorr weigh by a half-life. vol estimates volatility from each bar’s prices: from closes, or with Parkinson, Garman-Klass, Rogers-Satchell or Yang-Zhang, which use the high, the low and the gap from the previous close.
A bar with na in an input returns na and leaves the window as it was, so a window is the last length bars that had values. pandas would count the missing bar inside the window instead.

Regression

ml.ols(length, inputs) fits a least-squares line over the last length bars; ml.rls(inputs) learns from every bar so far, each older bar weighing forget times less. Each update takes this bar’s y and its list of x, and returns the coefficients, R², t-statistics and two honest numbers: fitted, the estimate of this bar’s y from what the model knew before it, and residual, the miss.
ridge keeps the fit steady when inputs move together; it leaves the intercept alone, as scikit-learn’s Ridge does. Give the inputs similar scales (z-scores, say) when you use it, so it weighs them alike.
The t-statistics assume each bar’s error is independent. Labels that overlap, such as 12-bar forward returns sampled every bar, share 11 bars each, and the t-statistics overstate how significant a coefficient is.

Labels a model cannot see early

To learn what came after a reading, a model needs the return that followed it, which does not exist until later. ml.forward(horizon, inputs) holds each bar’s inputs and hands them back with the log return since, horizon bars later and never sooner. Train on what it returns, and the model cannot learn from the future.
A model updated with na as y learns nothing that bar, so it can be updated on every bar as the rules ask, even before the first label. Grade a forecast the same way: hold it in a second ml.forward and correlate it with the return that arrives, as Order-flow forecast does.

Kalman filters

ml.kalman smooths a value that moves as a random walk and is seen with noise: it returns the level, its uncertainty, and each bar’s surprise. ml.kalmanBeta estimates y = α + βx with α and β drifting, the hedge ratio of a pairs trade, and returns the spread and its z-score. See Kalman pairs spread.

Principal components

ml.pca(inputs) finds the ways a list of numbers moves together over a window: RSI at many lengths, or many markets’ returns. Each bar it returns the scores (where the inputs sit on each component, what a model learns from), the share each component explains, the loadings, and each input’s residual, the part the components don’t explain.
The components are computed exactly, from the window’s covariance (or its correlations, with standardize), on closed bars. They are recomputed every refit bars and held in between, so a model fed the scores doesn’t have its inputs shift under it every bar. refit: 'auto', the default, recomputes every bar up to 20 inputs, then every 4 bars at 30 inputs, every 8 at 40 and every 16 at 50, to keep the cost near 20 inputs’. Each component’s largest loading is positive, so a component never flips sign from one refit to the next.

Forecasting from components, walk-forward

A model that keeps learning from ml.pca scores has the components move under it at every refit. When two smaller components swap places, its coefficients suddenly apply to the wrong one until it learns again. ml.pcr(inputs) avoids that. It fits the components and the regression on them together, on the same window, then freezes both, centre and scale included, until the next refit. That is a walk-forward test: each stretch is forecast by a fit that only saw the bars before it.
Feed it the pairs ml.forward returns. Once window pairs are in, it fits on closed bars every refit pairs, and fit.refitted is true on that bar. quantiles gives thresholds from the fit’s own in-sample forecasts, so “above the 99th percentile” means unusually strong by that fit’s standard. predict and scores use the frozen fit, and return na before the first. See RSI PCA forecast.

Matrices

linalg has matrices for scripts that build their own models: products, solve, inv, and the Cholesky, QR, symmetric eigen and singular value decompositions. A matrix made in a handler is a plain value; state.mat(rows, cols) keeps one across bars and rolls it back with the forming bar.
A singular solve or inv, or a cholesky of a matrix that is not positive definite, returns na throughout rather than stopping the script. Results are the same bits in every browser. A decomposition counts about n³ steps against the step budget.

Next step

Read other markets, intervals and 0xArchive’s data in data and timeframes.
Last modified on October 25, 2026