Library · Pine Script v6 · Library

Skipp Scoring

by skipp-dev· code credited to preuss_steffen

Skipp Scoring is a Pine Script v6 utility library that provides quantitative scoring functions for technical analysis scripts.

View on GitHub

GitHub stars1on the repository
Pine versionv6current
Lines of code156
Settings0inputs
LicenceNone statedfile: MPL-2.0
Last update2 days ago26 Oct 2026

Add It to Your TradingView Chart

  1. 1Copy the scriptPress Copy script above, or the copy button on the code below.
  2. 2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
  3. 3Paste over the templateCreate a new library, select all of the template text and paste. Press Save and give it a name.
  4. 4Publish or import itA library draws nothing. Publish it from the editor, then import its functions in your own scripts.

Source Code

156 lines of Pine Script v6 from pine/skipp_scoring.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.

skipp_scoring.pine
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © preuss_steffen

//@version=6
library("skipp_scoring", overlay = true)
// Last refreshed: 2026-07-03

import preuss_steffen/skipp_math/1 as m

// --------------------------------------------------
// Constants
// --------------------------------------------------
// 2026-08-26 (#4756): getter-functions -> `export const`. Werte
// unveraendert. `m.PRICE_EPS()` bleibt BEWUSST in Funktionsform: der Pin
// steht auf skipp_math/1, dessen API der Getter ist; die Form folgt beim
// Repin auf /2 (Publish-Reihenfolge: math zuerst).

export const float SIDEWAYS_EMA_THRESH = 0.005
export const float SIDEWAYS_ATR_THRESH = 0.015

// --------------------------------------------------
// Trend / Regime
// --------------------------------------------------

// @function Continuous trend strength in [-1, 1]
export trend_strength(float emaF, float emaS) =>
    float emaDiff = (emaF - emaS) / math.max(nz(emaS, 1), m.PRICE_EPS())
    math.max(-1.0, math.min(1.0, emaDiff / math.max(SIDEWAYS_EMA_THRESH, m.PRICE_EPS())))

// @function Discrete trend regime: +1 bull, -1 bear, 0 sideways
export trend_regime(float emaF, float emaS, float atrNorm) =>
    float emaDiff = (emaF - emaS) / math.max(nz(emaS, 1), m.PRICE_EPS())
    bool isSideways = math.abs(emaDiff) < SIDEWAYS_EMA_THRESH and atrNorm < SIDEWAYS_ATR_THRESH
    bool isBull = emaF > emaS and not isSideways
    bool isBear = emaF < emaS and not isSideways
    isBull ? 1.0 : isBear ? -1.0 : 0.0

// @function Composite state score in [-1, 1]
export state_score(float c, float emaF_tf, float emaS_tf, float r_tf, bool useSmoothTrend) =>
    float trend = useSmoothTrend ? trend_strength(emaF_tf, emaS_tf) : (emaF_tf > emaS_tf ? 1.0 : emaF_tf < emaS_tf ? -1.0 : 0.0)
    float mom   = r_tf > 55.0 ? 1.0 : r_tf < 45.0 ? -1.0 : 0.0
    float loc   = c > emaS_tf ? 0.5 : c < emaS_tf ? -0.5 : 0.0
    m.clamp01((trend + mom + loc + 2.0) / 4.0) * 2.0 - 1.0

// --------------------------------------------------
// Ensemble
// --------------------------------------------------

// @function Pullback quality score
export pullback_score(float c, float ef, float es, float bias) =>
    bias == 1.0 ? (c > ef ? 0.5 : c > es ? 1.0 : -1.0) :
     bias == -1.0 ? (c < ef ? 0.5 : c < es ? 1.0 : -1.0) : 0.0

// @function Weighted 4-factor ensemble in [-1, 1]
export ensemble4(float sA, float sB, float sC, float sD, float wA, float wB, float wC, float wD) =>
    float num = wA * sA + wB * sB + wC * sC + wD * sD
    float den = wA + wB + wC + wD
    float val = den == 0.0 ? 0.0 : num / den
    math.max(-1.0, math.min(1.0, val))

// @function Rate-of-change score in [-1, 1]
export roc_score(series float c, simple int rocL) =>
    float roc = ta.roc(c, rocL)
    float r   = na(roc) ? 0.0 : roc
    math.max(-1.0, math.min(1.0, r / 5.0))

// @function Volume relative to SMA, in [-1, 1]
export vol_score(series float vol, simple int volSmaLen) =>
    float sma = ta.sma(vol, volSmaLen)
    if na(vol) or vol == 0.0
        0.0
    else
        float ratio = na(sma) or sma == 0.0 ? 0.0 : (vol / sma - 1.0)
        math.max(-1.0, math.min(1.0, ratio))

// @function Bias from raw score
export bias_from_score(float score) =>
    score > 0.0 ? 1 : score < 0.0 ? -1 : 0

// @function Check if bull bias is consistent
export is_bull_bias(float score, float emaF_tf, float emaS_tf) =>
    score > 0.0 and emaF_tf > emaS_tf

// --------------------------------------------------
// Binning
// --------------------------------------------------

// @function Uniform bin index
export bin(float score, int bins) =>
    float u = (score + 1.0) * 0.5
    int b = int(math.floor(u * bins))
    b < 0 ? 0 : b > (bins - 1) ? (bins - 1) : b

// @function Fill quantile cuts from sorted array
export fill_cuts(float[] sorted, float[] cuts, int bins) =>
    int cutCount = bins - 1
    if cutCount > 0 and array.size(sorted) > 0
        int n = array.size(sorted)
        for i = 0 to cutCount - 1
            float frac = (i + 1.0) / bins
            int idx = int(math.floor(frac * (n - 1)))
            array.set(cuts, i, array.get(sorted, idx))

// @function Bin using quantile cuts with uniform fallback
export bin_quantile(float score, float[] cuts, int bins) =>
    if na(score)
        int(na)
    else if array.size(cuts) == 0 or na(array.get(cuts, 0))
        bin(score, bins)
    else
        int b = 0
        for i = 0 to array.size(cuts) - 1
            if score <= array.get(cuts, i)
                b := i
                break
            else
                b := i + 1
        math.max(0, math.min(bins - 1, b))

// @function 2D bin index. The score axis uses quantile cuts when
//           `cutsArr` is populated and falls back to uniform binning
//           otherwise (same contract as bin_quantile); the trend axis
//           is always uniform. Fixed 2026-07-08: `cutsArr` was accepted
//           but silently ignored (always uniform) — the exported
//           function had no callers, so implementing the documented
//           semantics breaks nobody and matches the legacy f_bin2D.
//           (Declared after bin_quantile — Pine resolves calls only to
//           previously defined functions.)
export bin2D(float score, float trendScore, int binsA, int binsB, float[] cutsArr) =>
    int a = bin_quantile(score, cutsArr, binsA)
    int b = int(math.floor((trendScore + 1.0) * 0.5 * binsB))
    b := b < 0 ? 0 : b > (binsB - 1) ? (binsB - 1) : b
    a * binsB + b

// @function Regime bin: 0=bear, 1=neutral, 2=bull
export regime_bin(float trendScore) =>
    trendScore > 0.5 ? 2 : trendScore < -0.5 ? 0 : 1

// @function Bucket index for calibration
export bucket(float p, int B) =>
    int b = int(math.floor(p * B))
    b < 0 ? 0 : b > (B - 1) ? (B - 1) : b

// @function Edges from 3-way probabilities
export edges3(float pU, float pF, float pD) =>
    [pU - pD, math.max(pU, math.max(pF, pD)) - (1.0 / 3.0)]

// @function Decision quality metric
export decision_quality(float pU, float pF, float pD, int nBin, int total) =>
    if na(pU) or na(pF) or na(pD) or nBin < 5 or total <= 0
        float(na)
    else
        float edge = math.max(pU, math.max(pF, pD)) - (1.0 / 3.0)
        float sampleFrac = nBin / math.max(1.0, float(total))
        float q = edge * math.sqrt(sampleFrac)
        m.clamp01(q)

Overview

Skipp Scoring calculates normalized market state scores ranging between -1 and +1, evaluating trend strength, discrete regimes (bullish, bearish, or sideways), rate of change, and volume relative to moving averages. Additionally, the library includes functions for assessing pullback quality relative to exponential moving averages and aggregating multi-factor metrics into a weighted ensemble score.

Details

Published by

skipp-dev on GitHub

Code credit

preuss_steffen, as written in the script's header

Type

Library, Pine Script v6

Draws

Library (no plots)

Markets

Any symbol

Timeframes

Any timeframe

Risk Notes

No repainting, lookahead or stacked entries were found in its code or README. That says nothing about how well it works: test it first.

Third-party code. ForexR did not write, test or endorse this script, and the summary above was generated automatically from its code and README. Indicators describe the past, and a strategy's backtest can look better than live trading, especially when a script repaints. Check it in the Strategy Tester and on a demo account before you rely on it.

Similar Pine Scripts

FunctionLinearRegression

by ricardosantos79
261 stars

This Pine Script v5 library provides functions to calculate and plot linear regression channels using sample point arrays. It evaluates paired X and Y arrays to calculate the regression slope, intercept, fitted values, maximum deviation, minimum deviation, and

Library v5 Trend
Updated 4 years ago · None stated GitHub repository of FunctionLinearRegression

PositionSizing

by iamrichardD
57 stars

This Pine Script v6 library calculates trade position sizes and provides risk management functions for external scripts. It computes position sizes from account equity, percentage risk, and stop-loss distance, and offers dynamic sizing adjustments based on vol

Library v6
Updated 1 year ago · Apache-2.0 GitHub repository of PositionSizing

Chart Patterns

by deepentropy
13 stars

Chart Patterns is a Pine Script v6 library designed to scan for and render technical chart patterns directly on the price chart. It defines custom user-defined types to configure scanning parameters, such as Zigzag pivot offsets, error ratios, flat ratios, and

Library v6 Repaints
Updated 6 months ago · MIT GitHub repository of Chart Patterns

AuthLib

by alboogycOdR
6 stars

AuthLib is a Pine Script utility library providing access control and state management structures for technical indicators. It checks callers against a hardcoded array of authorized TradingView usernames before executing operations. The library exports user-de

Library v5 SMC / ICT / price actionSessions & time
Updated 7 months ago · None stated GitHub repository of AuthLib

WebhookMessageLibrary

by TradersPost
6 stars

WebhookMessageLibrary is a helper library designed to construct structured JSON payload messages for automated trading integrations like TradersPost. It defines custom exported types and constants for trade actions, market sentiments, quantities, limit prices,

Library v5
Updated 1 year ago · None stated GitHub repository of WebhookMessageLibrary

PineDraw

by 345-strategies
5 stars

PineDraw is a Pine Script v6 library that provides object primitives for drawing and updating price levels on the chart. It enables indicators and strategies to maintain lines, boxes, and labels in place by updating existing objects instead of deleting and rec

Library v6 Support & resistance
Updated 2 days ago · MPL-2.0 GitHub repository of PineDraw

More libraries

Trade Your Charts With a Regulated Broker

Compare brokers that connect to TradingView, with spreads, minimum deposits and leverage side by side.

Compare brokers