Curved Price Channels (Zeiierman) for ThinkOrSwim

samer800

Moderator - Expert
VIP
Lifetime
kC45dgn.png


Author Message:

The Curved Price Channels (Zeiierman) is designed to plot dynamic channels around price movements, much like the traditional Donchian Channels, but with a key difference: the channels are curved instead of straight. This curvature allows the channels to adapt more fluidly to price action, providing a smoother representation of the highest high and lowest low levels.

Just like Donchian Channels, the Curved Price Channels help identify potential breakout points and areas of trend reversal. However, the curvature offers a more refined approach to visualizing price boundaries, making it potentially more effective in capturing price trends and reversals in markets that exhibit significant volatility or price swings.

The included trend strength calculation further enhances the indicator by offering insight into the strength of the current trend.

CODE:

CSS:
#// Indicator for TOS
#// © Zeiierman {
#indicator("Curved Price Channels (Zeiierman)",overlay=true, max_bars_back =
#// ~~ Tooltips {
#Hint trendLength: Trend Length defines the number of bars (or candles) used to calculate the core trendline. A longer length, such as 200, smooths out the trend, making it more stable but slower to react to price changes. This is useful in identifying long-term trends. Conversely, a shorter length, such as 20, makes the trendline more responsive to recent price action, capturing short-term movements.
#Hint multiplier: Multiplier adjusts the width of the curved price channels by scaling the impact of the adaptive size. A higher multiplier tightens the channels, making them more sensitive to price movements and capturing smaller fluctuations. This setting is useful for detecting minor changes in trends or during low-volatility periods. Conversely, a lower multiplier widens the channels, making them more forgiving and focusing on larger price moves.
#Hint trendStrengthLookback: Trend Strength Length defines the period over which the maximum and minimum ranges are calculated to normalize the trend strength. A longer length, such as 200, smooths the strength readings, making them more reliable for long-term analysis. A shorter length, like 50, makes the strength readings more sensitive to recent changes.
# Converted by Sam4Cok@Samer800    - 09/2024
#// ~~ Inputs {
input timeframe = AggregationPeriod.MIN;
input trendLength     = 100;
input multiplier = 6.0;
input showTrendline = yes;
input showCurvedChannel = yes;
input showTrendStrengthCandle = yes;
input candleOffset = 3;
input showTrendStrength = {Default "As Label", "As Bubbles", "Don't Show"};
input trendStrengthLookback  = 200;

def na = Double.NaN;
def last = IsNaN(close);
def current = GetAggregationPeriod();
def tf = Max(current, timeframe);
def lab; def bub;
Switch(showTrendStrength) {
Case "As Bubbles" :
    lab = no;
    bub = yes;
Case "Don't Show" :
    lab = no;
    bub = no;
Default :
    lab = yes;
    bub = no;
}
#/ ~~ Curved Price Channels {
#// Curved Price Channels Calculation Function
Script calcCurvedPriceChannels {
input length = 100;
input multi = 6;
input tf = 60000;
    def upperBand;
    def lowerBand;
    def tr = TrueRange(high(period = tf), close(period = tf), low(period = tf));
    def adaptiveSize = WildersAverage(tr, length);
    def lengthSquared = power(length, 2);
    def maxcloseUpper = Max(high(period = tf), if !upperBand[1] then close(period = tf) else upperBand[1]);
    def barsSinceUpperIncrease = if close(period = tf)  > upperBand[1] then 0 else barsSinceUpperIncrease[1] + 1;
    def upperAdjustmentFactor = adaptiveSize / lengthSquared * (barsSinceUpperIncrease + 1) * multi;
        upperBand = maxcloseUpper - upperAdjustmentFactor;
    def mincloseLower = Min(low(period = tf), if !lowerBand[1] then close(period = tf) else lowerBand[1]);
    def barsSinceLowerDecrease = if close(period = tf)  < lowerBand[1] then 0 else barsSinceLowerDecrease[1] + 1;
    def lowerAdjustmentFactor = adaptiveSize / lengthSquared * (barsSinceLowerDecrease + 1) * multi;
        lowerBand = mincloseLower + lowerAdjustmentFactor;
    def pvtHi = highest(upperBand, 1);
    def pvtLo = lowest(lowerBand, 1);
    def Up = if !pvtHi then upperBand else pvtHi;
    def Dn = if !pvtLo then lowerBand else pvtLo;
    def trendline = (Up + Dn) / 2;
    plot u = if isNaN(close) then Double.NaN else Up;
    plot d = if isNaN(close) then Double.NaN else Dn;
    plot T = Trendline;
}

def Up = calcCurvedPriceChannels(trendLength, multiplier, tf).u;
def Dn = calcCurvedPriceChannels(trendLength, multiplier, tf).d;
def trendline = calcCurvedPriceChannels(trendLength, multiplier, tf).t;

#// ~~ Curved Price Channels Plots {
def cond = last[-trendLength];

plot CurvedHigh = if showCurvedChannel then Up else na; #, "Curved High"
plot CurvedLow  = if showCurvedChannel then Dn else na; #, "Curved Low"
plot CurvedTrend = if !cond and showTrendline then trendline else na; # "Curved Trend"
plot CurvedTrend1 = if cond and showTrendline then trendline else na; # "Curved Trend"
CurvedHigh.SetDefaultColor(Color.GREEN);
CurvedLow.SetDefaultColor(Color.RED);
CurvedTrend1.SetStyle(Curve.SHORT_DASH);
CurvedTrend.AssignValueColor(if close > trendline then Color.CYAN else Color.MAGENTA);
CurvedTrend1.AssignValueColor(if close > trendline then Color.CYAN else Color.MAGENTA);

def p2 = Average(trendline, 20);

AddCloud(CurvedHigh, CurvedHigh - (CurvedHigh - p2) / 2.5, Color.DARK_GREEN, Color.DARK_GREEN);
AddCloud(CurvedLow, CurvedLow + (p2 - CurvedLow) / 2.5, Color.DARK_RED, Color.DARK_RED);

# Plot the new Chart

def n = candleOffset;
def loc = last[n - 1] and !last[n];
#// ~~ Range & Strength {
#// Calculate the distance of the close from the trendline relative to the range
def rangee           = up - dn;
def relativePosition = (close(period = tf) - trendline) / rangee;
#// Normalize the current range to get the trend strength
def maxRange        = highest(rangee, trendStrengthLookback);
def minRange        = lowest(rangee, trendStrengthLookback);
def normalizedRange = (rangee - minRange) / (maxRange - minRange);

#// Combine the relative position and the normalized range to calculate trend strength
def Strength    = relativePosition * normalizedRange;
def maxTrendStrength = highest(Strength, trendStrengthLookback);
def minTrendStrength = lowest(Strength, trendStrengthLookback);

def rndDiff = Strength ;
def labLoc = (trendline + close(period = tf)) / 2;

def candCond = showTrendStrengthCandle and loc;

AddChart(open = if candCond and rndDiff[n] > 0 then close(period = tf)[n] else na, high = trendline[n] ,
          low = close(period = tf)[n] , close = trendline[n], type = ChartType.CANDLE, growcolor = Color.CYAN);

AddChart(open = if candCond and rndDiff[n] < 0 then trendline[n] else na, high = close(period = tf)[n] ,
          low = trendline[n] , close = close(period = tf)[n], type = ChartType.CANDLE, growcolor =  Color.MAGENTA);

AddChart(open = if candCond then labLoc[n] else na, high = up[n] , low = dn[n] , close = labLoc[n],
         type = ChartType.CANDLE, growcolor =  Color.GRAY);

#-- Bubble
AddLabel(lab, "Trend Strength: " + AsPercent(rndDiff),  if rndDiff > 0 then Color.CYAN else Color.MAGENTA);
AddLabel(lab, "Max: " + AsPercent(maxTrendStrength), Color.CYAN);
AddLabel(lab, "Min: " + AsPercent(minTrendStrength), Color.MAGENTA);

AddChartBubble(bub and loc[1], labLoc[n+1], asPercent(rndDiff[n+1]),
               if rndDiff[n+1] > 0 then Color.CYAN else Color.MAGENTA);
AddChartBubble(bub and loc, up[n], asPercent(maxTrendStrength[n]), Color.CYAN);
AddChartBubble(bub and loc, dn[n], asPercent(minTrendStrength[n]), Color.MaGENTA, no);

#-- END of CODE
 

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
316 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