1Copy the scriptPress Copy script above, or the copy button on the code below.
2Open the Pine EditorOpen a TradingView chart and choose Pine Editor at the bottom of the screen.
3Paste over the templateCreate a new indicator, select all of the template text and paste. Press Save and give it a name.
4Add it to the chartPress Add to chart, then adjust the settings with the gear icon next to its name.
Source Code
166 lines of Pine Script v6 from permutation_entropy_regime.pine, published under MPL-2.0 (file header). Keep the author's credit and licence lines when you reuse it.
permutation_entropy_regime.pine
//@version=6
// Permutation Entropy Regime [Jayadev Rana]
// This source code is subject to the terms of the Mozilla Public License 2.0.
//
// Concept: classify the market into a "predictability regime" using the
// permutation entropy (Bandt-Pompe, embedding dimension 3) of recent closes.
// Low entropy = ordered / structured price (clean trend or clean oscillation);
// high entropy = disordered / random-walk chop. A drift-bias term splits
// structured regimes into Up / Down / Range. Computed on confirmed bars only.
indicator("Permutation Entropy Regime [Jayadev Rana]", shorttitle="PER", overlay=false, max_bars_back=200)
//------------------------------------------------------------------------------
// Inputs
//------------------------------------------------------------------------------
grpCore = "Core"
winLen = input.int(50, "Entropy Window (bars)", minval=10, maxval=150, group=grpCore, tooltip="Number of ordinal patterns used to estimate permutation entropy. Larger = smoother and slower to react; smaller = more responsive and noisier. Embedding dimension is 3 (compares 3 consecutive closes).")
smoothLen = input.int(3, "Predictability Smoothing", minval=1, maxval=50, group=grpCore, tooltip="EMA length applied to the raw predictability score to reduce single-bar jitter. Set 1 to disable.")
grpReg = "Regime"
rankLb = input.int(200, "Structure Rank Lookback", minval=20, maxval=500, group=grpReg, tooltip="History window used to percentile-rank the current predictability against its own past, so the regime cutoff adapts per instrument and timeframe.")
structLv = input.int(60, "Structured Level", minval=50, maxval=95, group=grpReg, tooltip="A Structure Rank at or above this value marks a structured (predictable) regime.")
chopLv = input.int(40, "Chop Level", minval=5, maxval=50, group=grpReg, tooltip="A Structure Rank at or below this value marks a random / chop regime. Between the two levels is Neutral.")
driftTh = input.float(0.15, "Drift Bias Threshold", minval=0.0, maxval=1.0, step=0.05, group=grpReg, tooltip="Minimum absolute drift bias (net share of up vs down closes over the window, -1..+1) needed to call a structured regime Up or Down rather than Range.")
grpVis = "Visuals"
colorBars = input.bool(true, "Color price bars by regime", group=grpVis, tooltip="Recolor the main chart candles using the current regime color.")
showBg = input.bool(true, "Shade this pane by regime", group=grpVis)
showDash = input.bool(true, "Show dashboard", group=grpVis)
dashPos = input.string("Top Right", "Dashboard position", options=["Top Right", "Top Left", "Bottom Right", "Bottom Left"], group=grpVis)
grpCol = "Colors"
cUp = input.color(#26a69a, "Structured Up", group=grpCol)
cDn = input.color(#ef5350, "Structured Down", group=grpCol)
cRange = input.color(#42a5f5, "Structured Range", group=grpCol)
cNeutral = input.color(#b0bec5, "Neutral", group=grpCol)
cChop = input.color(#ffa726, "Random / Chop", group=grpCol)
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
// Ordinal pattern id (0..5) of three values using strict rank comparison.
patternId(float a, float b, float c) =>
int ra = (a > b ? 1 : 0) + (a > c ? 1 : 0)
int rb = (b > a ? 1 : 0) + (b > c ? 1 : 0)
int rc = (c > a ? 1 : 0) + (c > b ? 1 : 0)
int id = ra * 2 + (rb > rc ? 1 : 0)
id := id < 0 ? 0 : id > 5 ? 5 : id
id
f1(float x) => na(x) ? "-" : str.tostring(x, "#.0")
f2(float x) => na(x) ? "-" : str.tostring(x, "#.00")
//------------------------------------------------------------------------------
// Permutation entropy (embedding dimension 3, delay 1)
//------------------------------------------------------------------------------
var array<float> hist = array.new<float>(6, 0.0)
float He = na
float predRaw = na
float driftBias = na
enoughBars = bar_index > winLen + 3
if enoughBars
for k = 0 to 5
array.set(hist, k, 0.0)
float driftSum = 0.0
for i = 0 to winLen - 1
float a = close[i]
float b = close[i + 1]
float c = close[i + 2]
int id = patternId(a, b, c)
array.set(hist, id, array.get(hist, id) + 1.0)
driftSum += math.sign(a - b)
float total = winLen
float ent = 0.0
for k = 0 to 5
float p = array.get(hist, k) / total
if p > 0.0
ent -= p * math.log(p)
He := ent / math.log(6)
predRaw := (1.0 - He) * 100.0
driftBias := driftSum / winLen
float predScore = ta.ema(predRaw, smoothLen)
float sRank = ta.percentrank(predScore, rankLb)
//------------------------------------------------------------------------------
// Regime classification
//------------------------------------------------------------------------------
bool hasRank = not na(sRank)
bool structured = hasRank and sRank >= structLv
bool chop = hasRank and sRank <= chopLv
color regimeColor = cNeutral
string regime = "Neutral"
if chop
regime := "Random / Chop"
regimeColor := cChop
else if structured
if driftBias > driftTh
regime := "Structured Up"
regimeColor := cUp
else if driftBias < -driftTh
regime := "Structured Down"
regimeColor := cDn
else
regime := "Structured Range"
regimeColor := cRange
var string prevRegime = ""
bool regimeChanged = prevRegime != "" and regime != prevRegime
var int barsInRegime = 0
barsInRegime := prevRegime == regime ? barsInRegime + 1 : 1
//------------------------------------------------------------------------------
// Alerts (bar close)
//------------------------------------------------------------------------------
bool aUp = barstate.isconfirmed and regime == "Structured Up" and barsInRegime == 1
bool aDn = barstate.isconfirmed and regime == "Structured Down" and barsInRegime == 1
bool aRange = barstate.isconfirmed and regime == "Structured Range" and barsInRegime == 1
bool aChop = barstate.isconfirmed and regime == "Random / Chop" and barsInRegime == 1
bool aChg = barstate.isconfirmed and regimeChanged
alertcondition(aUp, "Entered Structured Up", "Permutation Entropy Regime: Structured Up")
alertcondition(aDn, "Entered Structured Down", "Permutation Entropy Regime: Structured Down")
alertcondition(aRange, "Entered Structured Range", "Permutation Entropy Regime: Structured Range")
alertcondition(aChop, "Entered Random / Chop", "Permutation Entropy Regime: Random / Chop")
alertcondition(aChg, "Regime Changed", "Permutation Entropy Regime: regime changed")
//------------------------------------------------------------------------------
// Visuals
//------------------------------------------------------------------------------
plot(predScore, "Predictability", color=color.new(color.gray, 40), linewidth=1)
plot(sRank, "Structure Rank", color=regimeColor, linewidth=2)
hline(structLv, "Structured Level", color=color.new(color.green, 60), linestyle=hline.style_dashed)
hline(chopLv, "Chop Level", color=color.new(color.orange, 60), linestyle=hline.style_dashed)
hline(50, "Mid", color=color.new(color.gray, 80))
bgcolor(showBg and hasRank ? color.new(regimeColor, 90) : na, title="Regime background")
barcolor(colorBars and hasRank ? regimeColor : na, title="Regime bar color")
//------------------------------------------------------------------------------
// Dashboard
//------------------------------------------------------------------------------
tablePos = dashPos == "Top Right" ? position.top_right : dashPos == "Top Left" ? position.top_left : dashPos == "Bottom Right" ? position.bottom_right : position.bottom_left
var table dash = table.new(tablePos, 2, 8, border_width=1, frame_width=1, frame_color=color.new(color.gray, 50))
if showDash and barstate.islast
table.cell(dash, 0, 0, "Permutation Entropy Regime", text_color=color.white, bgcolor=color.new(color.black, 20), text_size=size.small)
table.cell(dash, 1, 0, "", bgcolor=color.new(color.black, 20))
table.cell(dash, 0, 1, "Regime", text_color=color.white, bgcolor=color.new(color.black, 40), text_size=size.small)
table.cell(dash, 1, 1, regime, text_color=color.white, bgcolor=color.new(regimeColor, 10), text_size=size.small)
table.cell(dash, 0, 2, "Structure Rank", text_color=color.gray, text_size=size.small)
table.cell(dash, 1, 2, f1(sRank), text_color=regimeColor, text_size=size.small)
table.cell(dash, 0, 3, "Predictability", text_color=color.gray, text_size=size.small)
table.cell(dash, 1, 3, f1(predScore), text_color=color.white, text_size=size.small)
table.cell(dash, 0, 4, "Norm. Entropy", text_color=color.gray, text_size=size.small)
table.cell(dash, 1, 4, na(He) ? "-" : f1(He * 100) + "%", text_color=color.white, text_size=size.small)
table.cell(dash, 0, 5, "Drift Bias", text_color=color.gray, text_size=size.small)
table.cell(dash, 1, 5, f2(driftBias), text_color=color.white, text_size=size.small)
table.cell(dash, 0, 6, "Bars in Regime", text_color=color.gray, text_size=size.small)
table.cell(dash, 1, 6, str.tostring(barsInRegime), text_color=color.white, text_size=size.small)
table.cell(dash, 0, 7, "Window / Dim", text_color=color.gray, text_size=size.small)
table.cell(dash, 1, 7, str.tostring(winLen) + " / 3", text_color=color.white, text_size=size.small)
prevRegime := regime
Overview
Permutation Entropy Regime [Jayadev Rana] calculates an entropy score to assess order versus randomness, smooths it into a predictability metric, and computes an adaptive percentile rank against historical data. A drift-bias calculation further categorizes structured environments into upward, downward, or ranging states, alongside neutral and chop classifications. The indicator plots in a separate pane with threshold guides, an informative metrics dashboard, background pane tinting, and optional candle recoloring on the main chart.
The inputs you can change from the gear icon on the chart. Defaults are the author's.
Setting
Type
Default
Variable
Entropy Window (bars)
int
50
winLen
Predictability Smoothing
int
3
smoothLen
Structure Rank Lookback
int
200
rankLb
Structured Level
int
60
structLv
Chop Level
int
40
chopLv
Drift Bias Threshold
float
0.15
driftTh
Color price bars by regime
bool
true
colorBars
Shade this pane by regime
bool
true
showBg
Show dashboard
bool
true
showDash
Dashboard position
string
Top Right
dashPos
Structured Up
color
#26a69a
cUp
Structured Down
color
#ef5350
cDn
Show all 15 settings
Setting
Type
Default
Variable
Structured Range
color
#42a5f5
cRange
Neutral
color
#b0bec5
cNeutral
Random / Chop
color
#ffa726
cChop
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.
This indicator scans a pasted list of symbols and shows matching long and short setups in a table in a separate pane. It uses a Supertrend crossover, then applies an ATR or fixed-point volatility range so quiet, sideways conditions can be skipped. Optional fil
Strategy-Picker evaluates market trend, momentum, and volatility across multiple timeframes (5m, 15m, and 60m) to recommend suitable options trading structures. It combines MACD, an 8-period EMA, and ADX readings with external VIX levels to suggest Put Credit
The Adaptive Cycle Detector estimates the dominant market cycle from WaveTrend oscillator zero-crossing frequency and applies smoothing to recommend adaptive indicator lengths. Fast markets with frequent crossings receive shorter lengths while slow swing marke
Manias, Panics and Crashes is a separate-pane market regime indicator that quantifies market sentiment and systemic risk. It processes technical metrics including RSI, moving averages, and volume alongside optional intermarket data such as VIX volatility and c
Elton's Screener is an indicator that runs in a separate pane and scores one of twenty selectable strategies, or auto-selects a route from the symbol type. It filters signals by a minimum confidence level and a higher-timeframe EMA trend alignment. ATR multipl
Meridian - Futures Context is an intraday analysis indicator designed for US index futures. It measures volume participation using relative volume, calculates rolling realized volatility, and evaluates trend context through VWAP slope and EMA structures. Displ