Adaptive Momentum Classifier [WillyAlgoTrader]📡 Adaptive Momentum Classifier is an overlay indicator that evaluates four independent market dimensions — momentum, trend, volatility position, and money flow — ranks each one against its own historical distribution using percentile scoring, and combines them into a single composite score (0–100%) that drives signal generation. Signals fire only when the composite score crosses a threshold with minimum feature agreement across axes, passes through five independent filters, and is confirmed on bar close.
The core idea: instead of using one indicator to generate signals, this tool treats four market dimensions as independent measurement axes, normalizes each to a uniform 0–1 scale via percentile ranking, weights and combines them into a consensus score, and then requires both the score threshold AND a minimum number of agreeing axes before allowing a signal. This multi-axis + agreement gate architecture filters out situations where a single strong reading (e.g., RSI spike) would trigger a false signal while the other dimensions disagree.
🧩 WHY THESE COMPONENTS WORK TOGETHER
Traditional signal generators face a fundamental problem: a single indicator measures one market dimension. RSI measures momentum speed but is blind to trend direction. MACD measures trend but ignores where price sits within its volatility envelope. Volume-based indicators measure flow but know nothing about price momentum. Using any one of these alone produces signals that ignore critical market context.
Simply combining indicators with AND/OR logic (e.g., "buy when RSI > 50 AND MACD > 0") doesn't solve the deeper problem: the indicators are on different scales, have different distributions, and their raw values aren't comparable. RSI = 55 and MACD histogram = 0.002 both "lean bullish" but you can't meaningfully average them.
This indicator solves both problems:
Step 1 — Orthogonal axis design: Each axis measures a genuinely different market dimension. Momentum (how fast), Trend (which direction), Volatility Position (where within the range), Flow (where is money going). They are deliberately chosen to be as independent as possible.
Step 2 — Percentile normalization: Each axis's raw value is ranked against its own recent history. "Is this RSI-ROC blend reading higher than 75% of the last 89 readings?" This converts every axis to a uniform 0–1 scale where 0.5 = median. Now all four axes are directly comparable and combinable.
Step 3 — Weighted consensus: The four normalized scores are combined with weights (Trend 1.2×, Momentum 1.0×, Flow 1.0×, Volatility 0.8×) into a single composite score. The weighting reflects that trend conviction is slightly more predictive than raw momentum.
Step 4 — Agreement gate: Even with a high composite score, the signal is blocked unless at least half the axes independently agree (each reading > 0.6 for bullish or < 0.4 for bearish). This prevents one extreme axis from dominating the composite and producing a false consensus.
Step 5 — Filter stack: Five independent filters (trend alignment, volatility regime, volume, score acceleration, HTF bias) provide additional context gates. The signal only fires when all enabled filters pass simultaneously.
No single component is useful alone. Percentile ranking without multiple axes just normalizes one indicator. Multiple axes without percentile ranking can't be meaningfully combined. A combined score without the agreement gate can be dominated by one outlier. And all of this without filters would still fire in unsuitable market conditions. The full pipeline is required.
🔍 WHAT MAKES IT ORIGINAL
1️⃣ Four-axis percentile scoring engine.
Each axis is built from two sub-components blended together, then converted to a 0–1 percentile rank against the scoring lookback window (default 89 bars). The percentile function counts what fraction of historical values are below the current value — producing a uniform distribution with no dead zones (unlike z-score normalization which compresses values near the mean).
Axis 1 — Momentum (weight 1.0):
Sub-components: RSI(13) centered at 50, and ROC(9). Each is percentile-ranked independently, then blended 60% RSI + 40% ROC. RSI provides stable momentum reading, ROC provides faster reaction to price acceleration. The blend captures both speed (ROC) and sustained momentum (RSI) in a single axis.
Axis 2 — Trend (weight 1.2):
Sub-components: MACD histogram (12/26/9), and EMA slope normalized by ATR. EMA slope = (EMA − EMA ) / (ATR × 5), making it scale-independent across instruments. Each percentile-ranked, blended 60% MACD + 40% slope. MACD histogram captures momentum of the trend itself (acceleration), while EMA slope captures sustained directional movement. This axis receives the highest weight (1.2) because directional conviction is the strongest single predictor of continuation.
Axis 3 — Volatility Position (weight 0.8):
Sub-components: Bollinger %B (21-period, showing where price sits within the band envelope, 0 = lower band, 1 = upper band), and ATR expansion ratio (current ATR / SMA of ATR over lookback). Combined as: (BB%B − 0.5) × min(ATR_ratio, 2.5), then percentile-ranked. This creates a directional volatility signal: price at upper band during volatility expansion scores high (strong bullish breakout), price at upper band during contraction scores lower (potential mean-reversion). The ATR ratio is capped at 2.5 to prevent extreme volatility spikes from distorting the axis. Lower weight (0.8) reflects that volatility position is a confirming factor, not a primary driver.
Axis 4 — Flow (weight 1.0, auto-disabled without volume):
Sub-components: MFI(13) centered at 50, and OBV slope (smoothed OBV EMA(21), slope = (OBV_EMA − OBV_EMA ) / |OBV_EMA|). Each percentile-ranked, blended 50/50. MFI combines price and volume into a single money flow reading, OBV slope shows whether accumulation is accelerating or decelerating. On instruments without volume data (forex), this axis returns 0.5 (neutral) and its weight drops to 0, so the composite score is calculated from three axes only.
2️⃣ Composite score with symmetric thresholds.
The four axes are combined: composite = (1.0 × momentum + 1.2 × trend + 0.8 × volatility_position + 1.0 × flow) / total_weight. Result is 0–1 where 0 = maximum bearish consensus, 0.5 = neutral, 1 = maximum bullish consensus. A buy signal fires when the composite crosses above the threshold (default 0.618). A sell signal fires when it crosses below (1 − threshold = 0.382). This creates symmetric entry conditions: the same strength of consensus is required for both directions.
3️⃣ Feature agreement gate.
Independent of the composite score, each axis is evaluated for directional agreement: > 0.6 = bullish vote, < 0.4 = bearish vote, 0.4–0.6 = abstain. The agreement ratio = max(bull_votes, bear_votes) / active_axes. Signals require agreement ≥ 0.5 (at least half the axes independently confirming the same direction). This prevents false signals from composite score averaging: if momentum = 0.95 but trend = 0.3 and volatility = 0.4, the composite might cross the threshold but only 1/4 axes agree — signal is blocked.
4️⃣ Score acceleration filter.
The rate of change of the composite score: acceleration = score − score . Signals require |acceleration| ≥ Min Score Acceleration (default 0.02). This filters out slow-drift crossovers where the score gradually creeps past the threshold without any decisive move — these typically represent noise, not genuine momentum shifts. Only fast, decisive threshold crosses produce signals.
5️⃣ Five-filter stack.
Each filter is independently toggleable:
— Trend Alignment (default On): price must be above EMA(50) for longs, below for shorts — prevents counter-trend entries
— Volatility Regime (default On): ATR ratio must be between 0.4 and 3.0 — suppresses signals during dead markets (ATR < 40% of average) and crash conditions (ATR > 300% of average)
— Volume Confirmation (default On): volume must exceed 80% of its 20-period SMA — confirms market participation. Auto-disabled on instruments without volume data
— Score Acceleration (default 0.02): described above. Set to 0 to disable
— Higher TF Bias (default disabled): when a timeframe is selected, price must be above/below EMA(21) on the higher timeframe for longs/shorts. Uses + lookahead_on for non-repainting HTF data
6️⃣ Direction lock — no consecutive same-direction signals.
After a buy signal fires, the next signal can only be a sell (and vice versa). This prevents signal clustering where multiple buy signals fire in sequence during a strong trend — you get one entry per direction until the trend reverses.
7️⃣ Four sensitivity presets.
Each preset overrides two parameters simultaneously:
— Conservative : threshold 0.80, lookback 150 — requires very strong consensus over a long history, fewer but higher-conviction signals
— Default : uses your manual settings (threshold 0.618, lookback 89)
— Aggressive : threshold 0.60, lookback 60 — lower bar for signals, shorter history, faster adaptation
— Scalping : threshold 0.55, lookback 40 — minimum consensus required, very short history, designed for 1–5M charts
The lookback affects all four axes simultaneously (percentile ranking window), so the entire scoring engine adapts as a unit.
8️⃣ Dynamic trend band.
A visual EMA ± 0.5× ATR band colored by the composite score: green (score > 55%), red (< 45%), yellow (neutral). This provides an at-a-glance trend context without needing to read the dashboard. The band width adapts to volatility automatically.
9️⃣ Signal strength classification.
Each signal is classified based on the composite score at the moment of firing: Strong (score ≥ 85%), Medium (≥ 75%), Weak (< 75%). Displayed in the dashboard and available in alert messages. This helps you size positions or filter setups based on conviction level.
⚙️ HOW IT WORKS — CALCULATION FLOW
Step 1 — Raw feature calculation: RSI(13), ROC(9), MACD(12/26/9) histogram, EMA slope (normalized by ATR), BB%B(21), ATR ratio, MFI(13), OBV slope — eight raw values computed from price and volume.
Step 2 — Percentile ranking: Each raw value is ranked against its own history over the scoring lookback (default 89 bars). The pctRank function iterates through the lookback window and counts what fraction of past values are below the current value. Result: 0.0 (lower than all history) to 1.0 (higher than all history). This normalization is performed for each of the eight sub-components independently.
Step 3 — Axis blending: Each pair of sub-components is blended into one axis score: momentum = 0.6 × pctRSI + 0.4 × pctROC, trend = 0.6 × pctMACD + 0.4 × pctSlope, volatility = pctVolPosition (single combined raw), flow = 0.5 × pctMFI + 0.5 × pctOBV.
Step 4 — Weighted composite: composite = (1.0 × momentum + 1.2 × trend + 0.8 × volatility + 1.0 × flow) / total_weight. On instruments without volume: flow weight = 0, total_weight = 3.0 instead of 4.0.
Step 5 — Threshold crossing: Buy triggers when composite crosses above the threshold (default 0.618) from below. Sell triggers when composite crosses below (1 − 0.618 = 0.382) from above. Both require barstate.isconfirmed.
Step 6 — Agreement check: Each axis is independently classified as bullish (> 0.6), bearish (< 0.4), or neutral. At least 50% of active axes must agree with the signal direction.
Step 7 — Filter stack: All five enabled filters must pass. Any failure blocks the signal.
Step 8 — Direction lock: Signal must be opposite to the last confirmed signal.
Step 9 — Emission: Buy (▲) or Sell (▼) label placed on the confirmed bar.
📖 HOW TO USE
🎯 Quick start:
1. Add the indicator to your chart
2. Select a sensitivity preset matching your style (or use Default)
3. The trend band immediately shows the current momentum bias (green/red/yellow)
4. Wait for a ▲ (buy) or ▼ (sell) label — check the dashboard for score and strength
5. Use the agreement ratio (e.g., 3/4) to confirm multi-axis consensus
👁️ Reading the chart:
— 🟢 Green trend band = bullish momentum (score > 55%)
— 🟡 Yellow trend band = neutral / transition zone
— 🔴 Red trend band = bearish momentum (score < 45%)
— 🟢 ▲ label below bar = confirmed buy signal
— 🔴 ▼ label above bar = confirmed sell signal
— Band width = current volatility (wider = more volatile)
📊 Dashboard fields:
— Trend: current composite direction (Bullish / Bearish / Neutral)
— Last Signal: most recent signal with bars elapsed
— Strength: signal quality (Strong / Medium / Weak)
— Score: current composite as percentage
— Agreement: how many axes confirm (e.g., 3/4)
— Volatility: ATR regime (High / Normal / Low)
— TF and version
🔧 Tuning guide:
— Too many signals: increase threshold (0.70–0.85), enable more filters, use Conservative preset
— Too few signals: decrease threshold (0.55–0.60), reduce lookback (50–70), use Aggressive preset
— Signals too late: shorten RSI/ROC/MACD lengths, reduce lookback
— Too many false signals in ranging markets: enable ADX-aware Volatility Regime filter, increase Min Score Acceleration to 0.03–0.05
— Scalping 1–5M: use Scalping preset (threshold 0.55, lookback 40), lower filter aggressiveness
— Swing 4H–1D: use Conservative preset (threshold 0.80, lookback 150), enable HTF bias filter
⚙️ KEY SETTINGS REFERENCE
⚙️ Main:
— Sensitivity Preset (default Default): Conservative / Default / Aggressive / Scalping
— Scoring Lookback (default 89): percentile ranking window — higher = more stable, lower = faster adaptation
— Signal Threshold (default 0.618): minimum composite score for buy signals (sell = 1 − threshold)
📊 Feature Engine:
— RSI Length (default 13) / ROC Length (default 9): momentum axis sub-components
— MACD Fast/Slow/Signal (default 12/26/9): trend axis MACD
— Bollinger Length (default 21): volatility position axis
— MFI Length (default 13) / OBV Smooth (default 21): flow axis
🔍 Filters:
— Trend Alignment (default On): EMA(34) trend direction gate
— Volatility Regime (default On): ATR ratio 0.4–3.0 range gate
— Volume Confirmation (default On): volume > 80% of 20-SMA
— Min Score Acceleration (default 0.02): minimum speed of score change
— Higher TF Bias (default Off): optional HTF EMA(21) alignment
🎨 Visual:
— Trend band (EMA ± 0.5× ATR, scored coloring)
— Background tint / Dynamic bar coloring (optional)
— Auto / Dark / Light theme
🔔 Alerts
— 🟢 BUY — ticker, price, timeframe, composite score
— 🔴 SELL — same fields
Both support plain text and JSON webhook format. Bar-close confirmed, direction-locked (no consecutive same-direction alerts).
⚠️ IMPORTANT NOTES
— 🚫 No repainting. All signals require barstate.isconfirmed. HTF bias uses + lookahead_on. A warmup period (max of lookback, MACD slow period, and trend EMA length, minimum 50 bars) prevents signals during insufficient data.
— 📐 The composite score is not a probability . A score of 80% means four market dimensions, percentile-ranked against recent history, strongly agree on bullish conditions. It measures consensus quality, not prediction accuracy.
— ⚖️ Percentile ranking is relative to the lookback window . A score of 0.9 means "higher than 90% of the last N bars" — it does not mean the same thing on different instruments or timeframes. Each chart creates its own distribution.
— 📊 The Flow axis (MFI + OBV) auto-disables on instruments without volume data (many forex pairs). The composite then runs on three axes with adjusted total weight. Signal quality is slightly lower without flow data but the other three axes remain fully functional.
— 🔒 Direction lock means you get one signal per trend leg . After a buy, only a sell can fire next. This prevents clustering but means you won't get "add to position" signals — the tool provides one entry per direction.
— 🔄 The agreement gate requires ≥ 50% of axes to independently confirm. On 4-axis instruments, this means ≥ 2. On 3-axis (no volume), ≥ 2. This is a deliberately moderate threshold — raising it to 75%+ would make signals extremely rare.
— 🛠️ This is a signal and analysis tool , not an automated trading bot. It classifies momentum consensus and generates signals — trade decisions remain yours.
— 🌐 Works on all markets and timeframes. Volume-dependent features auto-adapt to available data.
Pine Script® Indikator








