Multi-RSI Fibonacci Channel For ThinkOrSwim

cando13579

Active member
VIP
Adaptive Momentum Structure with Dynamic Fibonacci Zones
Author: CANDO13579

Concept Overview
The Multi-RSI Fibonacci Channel is a volatility-adaptive momentum framework that:

• Computes multiple advanced RSI variants (RSI, RSX, Ehlers, Harris, Slow, etc.)
• Smooths price with selectable MA types
• Builds a dynamic high-low channel on RSI
• Projects Fibonacci retracement levels inside the RSI range
• Highlights momentum expansion, compression, and reversal zones

It transforms RSI from a static oscillator into a structure-based momentum map.

Core Components
RSI Engine (Selectable)
ModePurpose
RSI / CutlerClassical momentum
Ehlers RSICycle-filtered, low lag
Harris RSIVolatility-weighted
RSXInstitutional grade smoothing
Slow RSITrend-confirmation
Rapid RSIScalping responsiveness

Adaptive RSI Channel
The channel is calculated from:
• Highest RSI over N bars
• Lowest RSI over N bars
• Dynamic range = High − Low
This creates a living RSI box that expands in trend and contracts in consolidation.

Fibonacci Momentum Zones
Inside the RSI range:
LevelMeaning
23.6%Shallow pullback
38.2%Trend continuation
50%Mean reversion pivot
61.8%Deep retracement
76.4%Exhaustion / trap zone
support & resistance inside momentum itself.

Color Logic

• RSI turns Lime → New momentum high
• RSI turns Pink → New momentum low
• Channel turns Green → Expansion
• Channel turns Brown → Compression
• Fib 50% = Balance line
• Fib 61.8% = Institutional reload zone

Multi-Timeframe Behavior
1–5 Minute (Scalping)
Settings​
RSI Period: 7–10​
Channel Period: 20​
RSI Type: RSX or Rapid​
MA: EMA​
Usage
• Trade from Fib 61.8 → Fib 23.6 in trend
• Fade at 76.4 when RSI color flips
• Use 50% as VWAP-like equilibrium
Signal Logic
• Bull: RSI rejects 61.8 and turns Lime
• Bear: RSI rejects 38.2 and turns Pink

15–30 Minute (Day Trading)
Settings​
RSI Period: 14​
Channel Period: 25​
RSI Type: Ehlers or RSX​
MA: SMMA​
Usage
• Trend continuation above Fib 38.2
• Mean reversion between 50 and 61.8
• Distribution when RSI stalls at channel top and color flips

1H–4H (Swing Trading)
Settings​
RSI Period: 21​
Channel Period: 50​
RSI Type: Slow RSI or Harris​
MA: LWMA​
Usage
• Accumulation = RSI compressing between 38.2–61.8
• Breakout = Channel expansion + RSI Lime at 61.8
• Trend failure = RSI falls below 38.2 and channel slopes down

Daily / Weekly (Position Trading)
Settings​
RSI Period: 21–34​
Channel Period: 100​
RSI Type: RSX​
MA: EMA​
Usage
• Long bias above Fib 50
• Institutional accumulation = RSI holds 61.8
• Macro tops = RSI fails at channel high with bearish color shift


Trend Continuation
  1. RSI pulls back to 38.2
  2. Channel still rising
  3. RSI turns Lime
  4. Entry with stop below 50
  5. Target channel high

  1. RSI compresses near 50
  2. Channel range tight
  3. Sudden expansion
  4. RSI breaks 61.8 with Lime
  5. Ride to 76.4 and upper band

Unlike standard RSI:

• It is context-aware (dynamic range)
• It uses institutional smoothing (RSX / Ehlers)
• It maps market structure onto momentum
• It provides objective retracement zones inside RSI
• It adapts automatically to any timeframe


Code:
# Multi RSI Fibonacci Channel
# BY CANDO13579
declare lower;

input RSI_Period = 14;
input Fib_Channel_Period = 25;
input Price_Smoothing_Period = 32;
input RSI_MA_Type = {default "EMA", "SMA", "SMMA", "LWMA"};
input Price_Source = {default "Close", "Open", "High", "Low", "HL2", "HLC3", "OHLC4"};
input RSI_Type = {default "RSI", "Cutler_RSI", "Ehlers_Smoothed_RSI", "Harris_RSI", "Rapid_RSI", "RSX", "Slow_RSI"};
input Show_Fibonacci_Levels = YES;

# Price Source
def price_src;
if (Price_Source == Price_Source."Open") {
    price_src = open;
} else if (Price_Source == Price_Source."High") {
    price_src = high;
} else if (Price_Source == Price_Source."Low") {
    price_src = low;
} else if (Price_Source == Price_Source."HL2") {
    price_src = hl2;
} else if (Price_Source == Price_Source."HLC3") {
    price_src = hlc3;
} else if (Price_Source == Price_Source."OHLC4") {
    price_src = ohlc4;
} else {
    price_src = close;
}

# Moving Average
def ma_smoothed;
if (Price_Smoothing_Period <= 1) {
    ma_smoothed = price_src;
} else {
    if (RSI_MA_Type == RSI_MA_Type."SMA") {
        ma_smoothed = Average(price_src, Price_Smoothing_Period);
    } else if (RSI_MA_Type == RSI_MA_Type."SMMA") {
        # SMMA (RMA) approximation
        ma_smoothed = CompoundValue(1, (ma_smoothed[1] * (Price_Smoothing_Period - 1) + price_src) / Price_Smoothing_Period, Average(price_src, Price_Smoothing_Period));
    } else if (RSI_MA_Type == RSI_MA_Type."LWMA") {
        ma_smoothed = WMA(price_src, Price_Smoothing_Period);
    } else {
        ma_smoothed = ExpAverage(price_src, Price_Smoothing_Period);
    }
}

def smoothed_price = ma_smoothed;

# RSI Calculation (Standard RSI)
def base_rsi = RSI(price = smoothed_price, length = RSI_Period);

# Cutler RSI (same as standard RSI)
def cutler_rsi = base_rsi;

# Ehlers Smoothed RSI
def ehlers_price = (smoothed_price + 2 * smoothed_price[1] + smoothed_price[2]) / 4;
def ehlers_change = ehlers_price - ehlers_price[1];
def ehlers_up = Max(ehlers_change, 0);
def ehlers_down = -Min(ehlers_change, 0);
def ehlers_up_sum = Sum(ehlers_up, RSI_Period);
def ehlers_down_sum = Sum(ehlers_down, RSI_Period);
def ehlers_rsi_value = if (ehlers_up_sum + ehlers_down_sum == 0) then 50 else 100 * ehlers_up_sum / (ehlers_up_sum + ehlers_down_sum);
def ehlers_rsi = ehlers_rsi_value;

# Harris RSI
def harris_change = smoothed_price - smoothed_price[1];
def harris_up = Max(harris_change, 0);
def harris_down = -Min(harris_change, 0);
def harris_up_sum = Sum(harris_up, RSI_Period);
def harris_down_sum = Sum(harris_down, RSI_Period);
def harris_up_count = Sum(harris_change > 0, RSI_Period);
def harris_down_count = Sum(harris_change < 0, RSI_Period);
def harris_avg_up = if harris_up_count > 0 then harris_up_sum / harris_up_count else 0;
def harris_avg_down = if harris_down_count > 0 then harris_down_sum / harris_down_count else 0;
def harris_rsi_value = if harris_avg_down == 0 then 100 else 100 - 100 / (1 + harris_avg_up / harris_avg_down);
def harris_rsi = harris_rsi_value;

# Rapid RSI
def rapid_rsi = base_rsi;

# RSX Calculation
script RSX_Indicator {
    input src = close;
    input len = 14;
  
    def mom = src - src[1];
    def abs_mom = AbsValue(mom);
  
    # Initialize variables
    def kg = 3.0 / (2.0 + len);
    def hg = 1.0 - kg;
  
    # First smoothing
    def mom1;
    def mom2;
    def moa1;
    def moa2;
  
    if IsNaN(mom1[1]) {
        mom1 = mom;
        mom2 = mom1;
        moa1 = abs_mom;
        moa2 = moa1;
    } else {
        mom1 = kg * mom + hg * mom1[1];
        mom2 = kg * mom1 + hg * mom2[1];
        moa1 = kg * abs_mom + hg * moa1[1];
        moa2 = kg * moa1 + hg * moa2[1];
    }
  
    def mom_smooth1 = 1.5 * mom1 - 0.5 * mom2;
    def moa_smooth1 = 1.5 * moa1 - 0.5 * moa2;
  
    # Second smoothing
    def mom3;
    def mom4;
    def moa3;
    def moa4;
  
    if IsNaN(mom3[1]) {
        mom3 = mom_smooth1;
        mom4 = mom3;
        moa3 = moa_smooth1;
        moa4 = moa3;
    } else {
        mom3 = kg * mom_smooth1 + hg * mom3[1];
        mom4 = kg * mom3 + hg * mom4[1];
        moa3 = kg * moa_smooth1 + hg * moa3[1];
        moa4 = kg * moa3 + hg * moa4[1];
    }
  
    def mom_smooth2 = 1.5 * mom3 - 0.5 * mom4;
    def moa_smooth2 = 1.5 * moa3 - 0.5 * moa4;
  
    # Third smoothing
    def mom5;
    def mom6;
    def moa5;
    def moa6;
  
    if IsNaN(mom5[1]) {
        mom5 = mom_smooth2;
        mom6 = mom5;
        moa5 = moa_smooth2;
        moa6 = moa5;
    } else {
        mom5 = kg * mom_smooth2 + hg * mom5[1];
        mom6 = kg * mom5 + hg * mom6[1];
        moa5 = kg * moa_smooth2 + hg * moa5[1];
        moa6 = kg * moa5 + hg * moa6[1];
    }
  
    def mom_smooth3 = 1.5 * mom5 - 0.5 * mom6;
    def moa_smooth3 = 1.5 * moa5 - 0.5 * moa6;
  
    def rsx_value = if moa_smooth3 == 0 then 50 else ((mom_smooth3 / moa_smooth3 + 1) * 50);
    def rsx_final = if rsx_value > 100 then 100 else if rsx_value < 0 then 0 else rsx_value;
  
    plot result = rsx_final;
}

def rsx_rsi = RSX_Indicator(smoothed_price, RSI_Period);

# Slow RSI (smoothed standard RSI)
def slow_rsi = WildersAverage(base_rsi, RSI_Period);

# Select RSI type
def rsi_val;
if (RSI_Type == RSI_Type."Cutler_RSI") {
    rsi_val = cutler_rsi;
} else if (RSI_Type == RSI_Type."Ehlers_Smoothed_RSI") {
    rsi_val = ehlers_rsi;
} else if (RSI_Type == RSI_Type."Harris_RSI") {
    rsi_val = harris_rsi;
} else if (RSI_Type == RSI_Type."Rapid_RSI") {
    rsi_val = rapid_rsi;
} else if (RSI_Type == RSI_Type."RSX") {
    rsi_val = rsx_rsi;
} else if (RSI_Type == RSI_Type."Slow_RSI") {
    rsi_val = slow_rsi;
} else {
    rsi_val = base_rsi;
}

# Channel Calculations
def rsi_high = Highest(rsi_val, Fib_Channel_Period);
def rsi_low = Lowest(rsi_val, Fib_Channel_Period);
def rng = rsi_high - rsi_low;
def upper_band = rsi_high;
def lower_band = rsi_low;
def mid_band = (rsi_high + rsi_low) / 2;

# Fibonacci Levels
def fib236_level = rsi_low + 0.236 * rng;
def fib382_level = rsi_low + 0.382 * rng;
def fib500_level = mid_band;
def fib618_level = rsi_low + 0.618 * rng;
def fib764_level = rsi_low + 0.764 * rng;

# Color Calculations
rec upper_color_idx = if IsNaN(upper_band[1]) then 0 else
                     if upper_band > upper_band[1] then 1 else
                     if upper_band < upper_band[1] then 2 else
                     upper_color_idx[1];

rec lower_color_idx = if IsNaN(lower_band[1]) then 0 else
                     if lower_band > lower_band[1] then 1 else
                     if lower_band < lower_band[1] then 2 else
                     lower_color_idx[1];

rec rsi_color_idx = if (rsi_val == rsi_high and rsi_high != rsi_low) then 1 else
                   if (rsi_val == rsi_low and rsi_high != rsi_low) then 2 else
                   if IsNaN(rsi_color_idx[1]) then 0 else
                   rsi_color_idx[1];

# Define Colors
DefineGlobalColor("UpperLime", CreateColor(0, 255, 0));  # Lime
DefineGlobalColor("UpperBrown", CreateColor(244, 164, 96));  # Sandy Brown
DefineGlobalColor("RSIPink", CreateColor(255, 138, 197));  # Pink
DefineGlobalColor("FillGreen", CreateColor(221, 247, 221));  # Light Green
DefineGlobalColor("FillOrange", CreateColor(253, 238, 227));  # Light Orange

# Plot RSI Line
plot RSI_Line = rsi_val;
RSI_Line.AssignValueColor(
    if rsi_color_idx == 1 then GlobalColor("UpperLime")
    else if rsi_color_idx == 2 then GlobalColor("RSIPink")
    else Color.GRAY
);
RSI_Line.SetLineWeight(2);
RSI_Line.SetDefaultColor(Color.GRAY);

# Plot Channel Bands
plot UpperBand = upper_band;
UpperBand.AssignValueColor(
    if upper_color_idx == 1 then GlobalColor("UpperLime")
    else if upper_color_idx == 2 then GlobalColor("UpperBrown")
    else Color.GRAY
);
UpperBand.SetLineWeight(1);
UpperBand.SetStyle(Curve.FIRM);

plot LowerBand = lower_band;
LowerBand.AssignValueColor(
    if lower_color_idx == 1 then GlobalColor("UpperLime")
    else if lower_color_idx == 2 then GlobalColor("UpperBrown")
    else Color.GRAY
);
LowerBand.SetLineWeight(1);
LowerBand.SetStyle(Curve.FIRM);

# Plot Mid Band (hidden, used for fill)
plot MidBand = mid_band;
MidBand.SetDefaultColor(Color.CURRENT);
MidBand.Hide();

# Fibonacci Levels (optional)
plot Fib236Line = if Show_Fibonacci_Levels then fib236_level else Double.NaN;
Fib236Line.SetDefaultColor(Color.GRAY);
Fib236Line.SetStyle(Curve.FIRM);  # Changed to solid line

plot Fib382Line = if Show_Fibonacci_Levels then fib382_level else Double.NaN;
Fib382Line.SetDefaultColor(Color.GRAY);
Fib382Line.SetStyle(Curve.FIRM);  # Changed to solid line

plot Fib500Line = if Show_Fibonacci_Levels then fib500_level else Double.NaN;
Fib500Line.SetDefaultColor(Color.GREEN);  # Changed to green
Fib500Line.SetStyle(Curve.FIRM);  # Changed to solid line

plot Fib618Line = if Show_Fibonacci_Levels then fib618_level else Double.NaN;
Fib618Line.SetDefaultColor(CreateColor(255, 165, 0));  # Changed to orange
Fib618Line.SetStyle(Curve.FIRM);  # Changed to solid line

plot Fib764Line = if Show_Fibonacci_Levels then fib764_level else Double.NaN;
Fib764Line.SetDefaultColor(Color.GRAY);
Fib764Line.SetStyle(Curve.FIRM);  # Changed to solid line

# Add fills
#AddCloud(UpperBand, MidBand, GlobalColor("FillGreen"), GlobalColor("FillGreen"));
#AddCloud(MidBand, LowerBand, GlobalColor("FillOrange"), GlobalColor("FillOrange"));


# Overbought/Oversold lines
plot OverboughtLine = 70;
OverboughtLine.SetDefaultColor(Color.GRAY);
OverboughtLine.SetStyle(Curve.SHORT_DASH);

plot OversoldLine = 30;
OversoldLine.SetDefaultColor(Color.GRAY);
OversoldLine.SetStyle(Curve.SHORT_DASH);
 
Last edited by a moderator:

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
463 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top