PRANK -- Percentile Rank

Contents


Overview

Percentile Rank measures where the current closing price ranks among the last N closing prices, expressed as a percentage from 0 to 100. If the current price is the lowest close in the lookback window, the Percentile Rank is 0. If it is the highest, the Percentile Rank is 100. A value of 25 means the current price is higher than 25% of the closes in the window.

The calculation is simple: count how many of the last N closes are less than or equal to the current close, divide by N, and multiply by 100. No assumptions about distribution shape, no parameters beyond the lookback period. This simplicity is its strength.

The key advantage of Percentile Rank over Z-Score: it is distribution-free. Z-Score assumes prices are approximately normally distributed to interpret its thresholds (e.g., "Z = -2 means bottom 2.5%"). Percentile Rank makes no such assumption. A Percentile Rank of 5 means "the current price is in the bottom 5% of the last N closes" regardless of whether prices are normally distributed, skewed, or have fat tails. For crypto markets, where returns are decidedly non-normal, this non-parametric property is valuable. Percentile Rank tells you exactly what it says -- no statistical assumptions required.


Format

prank_{period}

The period defines the lookback window -- how many recent closing prices are compared against the current close.

ExamplePeriodUse Case
prank_5050Standard -- ranks price among the last 50 closes, good for short-to-medium-term context
prank_100100Slower -- ranks price within a broader window, better for swing trading and position sizing
prank_200200Long-term -- provides context against a large historical sample, fewer extremes

Period range: 10 to 500.

Value range: 0 to 100 (always). 0 = current price is the lowest close in the window. 100 = current price is the highest close in the window.


Understanding Percentile Rank Values

Percentile Rank values are bounded between 0 and 100 and have an intuitive interpretation that does not depend on the asset or timeframe. A value of 10 means "cheaper than 90% of recent closes" whether you are looking at BTC on the hourly chart or ETH on the daily chart.

Percentile RankMeaningTrading Interpretation
95 -- 100Price is at or near the highest close in the windowExtremely expensive relative to recent history. Potential top. Contrarian sell zone.
75 -- 95Price is in the upper quartileElevated. Market has been rallying. Trend-following strategies may stay long; mean-reversion strategies may start scaling out.
25 -- 75Price is in the middle rangeNormal territory. No strong signal from percentile rank alone.
5 -- 25Price is in the lower quartileDepressed. Market has pulled back. Starting to get interesting for dip buyers.
0 -- 5Price is at or near the lowest close in the windowExtremely cheap relative to recent history. Potential bottom. Contrarian buy zone.

Note

Percentile Rank is relative to the lookback window. A prank_50 of 5 means "bottom 5% of the last 50 closes" -- it says nothing about where price stands relative to the last 200 or 500 closes. Longer periods provide more historical context but react more slowly to recent trends.


Understanding Operators with Percentile Rank

Percentile Rank is a contrarian positioning indicator. It tells you where price sits in the context of recent history. Extreme lows suggest buying opportunities; extreme highs suggest selling opportunities.

> (Greater Than) -- State-Based

What it does: The trigger is true on every candle where Percentile Rank is above the threshold.

On the chart: Price is ranking high among recent closes. The closer to 100, the closer price is to its recent high watermark. This trigger stays active for as long as the Percentile Rank remains above the threshold.

[[actions.triggers]]
indicator = "prank_100"
operator = ">"
target = "95"
timeframe = "1h"

Typical use: "Price is near the top of its recent range -- consider taking profit or reducing exposure." When Percentile Rank exceeds 95, the current price is higher than 95% of the last 100 closes. This is a contrarian signal that the move may be overextended.

< (Less Than) -- State-Based

What it does: The trigger is true on every candle where Percentile Rank is below the threshold.

On the chart: Price is ranking low among recent closes. The closer to 0, the closer price is to its recent low point. This trigger stays active for as long as Percentile Rank remains below the threshold.

[[actions.triggers]]
indicator = "prank_100"
operator = "<"
target = "5"
timeframe = "1h"

Typical use: "Price is near the bottom of its recent range -- consider buying." When Percentile Rank drops below 5, the current price is lower than 95% of the last 100 closes. This is the core contrarian buy signal. Price is historically cheap within the lookback window.

cross_above -- Event-Based

What it does: Fires once, at the exact candle where Percentile Rank transitions from below the threshold to above it. The previous candle had Percentile Rank <= the target, and the current candle has Percentile Rank > the target.

[[actions.triggers]]
indicator = "prank_100"
operator = "cross_above"
target = "50"
timeframe = "1h"

Typical use: Detect the moment price crosses above the median of its recent range. This can serve as an exit signal for mean-reversion trades: you bought in the bottom percentile, and now price has recovered to the middle of its range -- the reversion is complete.

cross_below -- Event-Based

What it does: Fires once, at the exact candle where Percentile Rank transitions from above the threshold to below it. The previous candle had Percentile Rank >= the target, and the current candle has Percentile Rank < the target.

[[actions.triggers]]
indicator = "prank_100"
operator = "cross_below"
target = "10"
timeframe = "1h"

Typical use: Detect the exact moment price falls into the bottom percentile zone. Unlike < which stays active the entire time Percentile Rank is below 10, cross_below fires only at the transition -- giving you a single entry signal per dip.

Why: While Percentile Rank produces integer-like values more often than Z-Score, exact matches are still unreliable for triggering. Use > or < instead.

Choosing the right operator

  • Use < with a low threshold (e.g., 5 or 10) to buy when price is at the bottom of its recent range. This is the most common Percentile Rank operator.
  • Use > with a high threshold (e.g., 90 or 95) to sell or take profit when price is at the top of its recent range.
  • Use cross_below to enter once per dip (fires at the moment of transition, not on every candle).
  • Use cross_above to detect the moment price recovers to mid-range (exit signal).

TOML Examples

Buy the Bottom 5th Percentile

The classic contrarian trade: buy when the current price is lower than 95% of the last 100 closes. This is a purely statistical signal -- price is at the extreme low of its recent range. Add a trend filter to avoid buying into a sustained downtrend.

[[actions]]
type = "open_long"
amount = "100 USDC"

  [[actions.triggers]]
  indicator = "prank_100"
  operator = "<"
  target = "5"
  timeframe = "1h"

  [[actions.triggers]]
  indicator = "sma_50"
  operator = ">"
  target = "sma_200"
  timeframe = "1d"

Exit at 60th Percentile

Close the position when price recovers to the 60th percentile of its recent range. This exits above the median, capturing the majority of the reversion move without waiting for price to reach the top of the range (which may never happen).

[[actions]]
type = "close_long"
amount = "100%"

  [[actions.triggers]]
  indicator = "prank_100"
  operator = "cross_above"
  target = "60"
  timeframe = "1h"

Percentile Rank with RSI Confluence

Combine Percentile Rank with RSI for double confirmation. Both indicators must agree that price is depressed: Percentile Rank says the price is in the bottom 10% of its recent range, and RSI says momentum is oversold. The confluence of two independent signals increases confidence in the entry.

[[actions]]
type = "open_long"
amount = "100 USDC"

  [[actions.triggers]]
  indicator = "prank_100"
  operator = "<"
  target = "10"
  timeframe = "1h"

  [[actions.triggers]]
  indicator = "rsi_14"
  operator = "<"
  target = "30"
  timeframe = "1h"

  [[actions.triggers]]
  indicator = "ema_21"
  operator = ">"
  target = "ema_55"
  timeframe = "1d"

DCA at Different Percentile Levels

Dollar-cost average into a position at progressively lower percentile levels. The deeper the dip, the larger the allocation. This creates a tiered entry strategy that averages into a position more aggressively as price becomes cheaper relative to recent history.

# Light entry at 15th percentile
[[actions]]
type = "open_long"
amount = "50 USDC"

  [[actions.triggers]]
  indicator = "prank_100"
  operator = "cross_below"
  target = "15"
  timeframe = "4h"

# Medium entry at 8th percentile
[[actions]]
type = "open_long"
amount = "100 USDC"

  [[actions.triggers]]
  indicator = "prank_100"
  operator = "cross_below"
  target = "8"
  timeframe = "4h"

# Heavy entry at 3rd percentile
[[actions]]
type = "open_long"
amount = "200 USDC"

  [[actions.triggers]]
  indicator = "prank_100"
  operator = "cross_below"
  target = "3"
  timeframe = "4h"

Tips

Percentile Rank is backward-looking

A Percentile Rank of 0 means price is the lowest close in the last N periods -- but it says nothing about whether price will continue falling. In a sustained downtrend, price can print a Percentile Rank of 0 on every new candle as it keeps making new lows. Always combine Percentile Rank with a trend filter to avoid buying into an accelerating decline.

Distribution-free -- no assumptions needed

Unlike Z-Score, which interprets its thresholds based on a normal distribution assumption, Percentile Rank is completely non-parametric. A Percentile Rank of 5 literally means "current price is lower than 95% of the last N closes." No bell curve required. For crypto markets with fat tails and skewed returns, this is an advantage -- the number means exactly what it says.

Compare with Z-Score for a fuller picture

Z-Score and Percentile Rank often agree, but when they diverge, it is informative. If Z-Score says -3 (extreme) but Percentile Rank says 15 (not that extreme), it means price is far from the mean but not actually near the lowest close -- volatility has expanded the Z-Score. Combining both gives you a parametric and non-parametric view of the same question: "Is this price cheap?"

Longer periods for swing trading, shorter for scalping

A prank_50 reaching 5 means price is the cheapest of the last ~2 days of hourly candles -- a short-term dip. A prank_200 reaching 5 means price is the cheapest of the last ~8 days of hourly candles -- a more significant pullback. Choose your period based on your holding horizon: shorter periods for quick mean-reversion trades, longer periods for swing trades that may take days to play out.