# trend_type_8bars_tv_01
# https://usethinkscript.com/threads/convert-tradingview-trend-type-indicator-by-bobrivera990.13189/
# Convert Tradingview - Trend Type Indicator by BobRivera990
# LLP 10/30
# https://www.tradingview.com/v/zsDLpeBT/
# https://www.tradingview.com/script/zsDLpeBT-Trend-Type-Indicator-by-BobRivera990/
# Hi, someone please help to convert?
#-----------------------
#https://www.tradingview.com/script/zsDLpeBT-Trend-Type-Indicator-by-BobRivera990/
#Usage:
#The purpose of this indicator is to programmatically determine the type of price trend using technical analysis tools.
#You can do a quick check on the asset’s higher and lower time frames. For example, if you are trading on an H1 chart, you can check the m5 chart to ensure that the trend is in the same direction and similarly check the H4 chart to ensure that the higher time frame price is also moving in the same direction.
#If multiple time frame charts confirm a similar trend, then it is considered a very strong trend and ideal for Trend trading.
#Remarks:
#By default, the last status is related to 8 periods before the latest closing price.
#Related definitions:
#The three basic types of trends are up, down, and sideways.
#1. Uptrend
#An uptrend describes the price movement of a financial asset when the overall direction is upward. The uptrend is composed of higher swing lows and higher swing highs.
#Some market participants ("long" trend traders) only choose to trade during uptrends.
#2. Downtrend
#A downtrend refers to the price action of a security that moves lower in price as it fluctuates over time.
#The downtrend is composed of lower swing lows and lower swing highs.
#3. Sideways
#A sideways trend is the horizontal price movement that occurs when the forces of supply and demand are nearly equal. This typically occurs during a period of consolidation before the price continues a prior trend or reverses into a new trend.
#How it works:
#Step 1: Sideways Trend Detection
#In this step we want to distinguish the sideways trend from uptrend and downtrend. For this purpose, we use two common technical analysis tools: ATR and ADX
#1. Average True Range (ATR)
#The average true range (ATR) is a technical analysis indicator that measures market volatility .
#We also use a 20-period moving average of the ATR.
#When the ATR is below the average of its last 20-periods, it means that the rate of price volatility has decreased and we conclude that the current trend is sideways
#2. Average Directional Index ( ADX )
#The average directional index ( ADX ) is a technical analysis indicator used by some traders to determine the strength of a trend.
#The trend has strength when ADX is above 25.
#So when the ADX is less than or equal to 25, there is no strong trend, and we conclude that the current type of trend is sideways.
#Step 2: Detect uptrend from downtrend
#If it turns out that the current price trend is not sideways, then it is either uptrend or downtrend.
#For this purpose, we use plus and minus directional Indicators (+ DI & -DI ).
#A general interpretation would be that during a strong trend, when +DI is higher than -DI , it is an uptrend. When -DI is higher than +DI , it is a downtrend.
#Parameters:
#"Use ATR …" ________________________// Use Average True Range (ATR) to detect Sideways Movements
#"ATR Length"_______________________ // length of the Average True Range (ATR) used to detect Sideways Movements
#"ATR Moving Average Type" ___________// Type of the moving average of the ATR used to detect Sideways Movements
#"ATR MA Length" ____________________// length of the moving average of the ATR used to detect Sideways Movements
#"Use ADX ..."_______________________ // Use Average Directional Index ( ADX ) to detect Sideways Movements
#"ADX Smoothing”____________________// length of the Average Directional Index ( ADX ) used to detect Sideways Movements
#"DI Length"_________________________// length of the Plus and Minus Directional Indicators ( +DI & -DI ) used to determine the direction of the trend
#"ADX Limit" ________________________// A level of ADX used as the boundary between Trend Market and Sideways Market
#"Smoothing Factor"__________________// Factor used for smoothing the oscillator
#"Lag"______________________________// lag used to match indicator and chart
#-----------------------------
declare lower;
def na = double.nan;
def bn = barnumber();
# last bar ( most recent)
#def lastbar = !isnan(close[0]) and isnan(close[-1]);
# ref - averages
#def price = close;
#input ma1_len = 11;
#input ma1_type = AverageType.EXPONENTIAL;
#def ma1 = MovingAverage(ma1_type, price, ma1_len);
#input show_lines = yes;
#plot z1 = if show_lines then ma1 else na;
#z1.setdefaultcolor(getcolor(1));
#z1.hidebubble();
#-------------------------
# create pine functions
script change {
input price = close;
input offset = 1;
plot diff = price - price[offset];
}
#https://www.tradingview.com/pine-script-reference/v4/#fun_change
#change
#Difference between current value and previous, x - x[y].
#change(source, length) → series[float]
script na {
input a = 0;
plot z = if isnan(a) then 1 else 0;
}
#na
#Test value if it's a NaN.
#na(x) → bool
#na(x) → series[bool]
#RETURNS
#true if x is not a valid number (x is NaN), otherwise false.
script nz {
input a = 0;
input b = 0;
plot z = if isnan(a) then b else a;
}
#Replaces NaN values with zeros (or given value) in a series.
#nz(x, y) → integer
#EXAMPLE
#nz(sma(close, 100))
#RETURNS
#Two args version: returns x if it's a valid (not NaN) number, otherwise y
#One arg version: returns x if it's a valid (not NaN) number, otherwise 0
#ARGUMENTS
#x (series) Series of values to process.
#y (float) Value that will be inserted instead of all NaN values in x series.
script rma {
input source = CLOSE;
input length = 14;
def alpha = 1 / length;
def ma = alpha * source + (1 - alpha) * ma[1];
plot rma = ma;
};
# https://usethinkscript.com/threads/pine-functions-converted-to-a-tos-script-not-pine-studies.11424/#post-102505
script tr {
input high = high;
input close = close;
input low = low;
plot TrueRangeTS = Max(close[1], high) - Min(close[1], low);
}
# https://tlc.thinkorswim.com/center/reference/thinkScript/Functions/Tech-Analysis/TrueRange
#script atr_td {
# # ATR TD Ameritrade
# input length = 14;
# input averageType = AverageType.WILDERS;
# plot ATR = MovingAverage(averageType, TrueRange(high, close, low), length);
#}
#def smooth=0;
script fixnan {
input data1 = 0;
# def init = 0;
def data2;
if barnumber() == 1 then {
data2 = 0;
} else if IsNaN(data1) then {
data2 = data2[1];
} else {
data2 = data1;
}
plot valid = data2;
}
#def data1 = ..a variable with nan values..
#def data2 = fixnan(data1);
# https://usethinkscript.com/threads/pine-functions-converted-to-a-tos-script-not-pine-studies.11424/#post-99584
#-----------------------
#// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
#// © BobRivera990
#//@version=4
#study(title = "Trend Type Indicator by BobRivera990", overlay = false)
#//==================================================[Inputs]============================================
# useAtr = input(true, title = "Use ATR to detect Sideways Movements")
# // Use Average True Range (ATR) to detect Sideways Movements
input useAtr = yes;
# atrLen = input(14, minval = 1, title = "ATR Length")
# // length of the Average True Range (ATR) used to detect Sideways Movements
input atrLen = 14;
# atrMaType = input("SMA", options = ["SMA", "EMA"], title = "ATR Moving Average Type")
# // Type of the moving average of the ATR used to detect Sideways Movements
input atrMaType = AverageType.simple;
# atrMaLen = input(20, minval = 1, title = "ATR MA Length")
# // length of the moving average of the ATR used to detect Sideways Movements
input atrMaLen = 20;
# useAdx = input(true, title = "Use ADX to detect Sideways Movements")
# // Use Average Directional Index (ADX) to detect Sideways Movements
input useAdx = yes;
# adxLen = input(14, minval = 1, maxval = 50, title = "ADX Smoothing")
# // length of the Average Directional Index (ADX) used to detect Sideways Movements
input adxLen = 14;
# diLen = input(14, minval = 1, title = "DI Length")
# // length of the Plus and Minus Directional Indicators (+DI & -DI) used to determine the direction of the trend
input diLen = 14;
# adxLim = input(25, minval = 1, title = "ADX Limit")
# // A level of ADX used as the boundary between Trend Market and Sideways Market
input adxlim = 25;
# smooth = input(3, minval = 1, maxval = 5, title = "Smoothing Factor")
# // Factor used for smoothing the oscillator
input smooth = 3;
# lag = input(8, minval = 0, maxval = 15, title = "Lag")
# // lag used to match indicator and chart
input lag = 8;
#//=======================================================================================================================
#//==========================================[Initial Calculations]===============================================
# atr = atr(atrLen)
# // Calculate the Average True Range (ATR)
def atr = atr(atrLen);
# atrMa = atrMaType == "EMA" ? ema(atr, atrMaLen) : sma(atr, atrMaLen)
# // Calculate the moving average of the ATR
def atrma = MovingAverage(atrMaType, atr, atrmalen);
# up = change(high)
# // Calculate parameter related to ADX, +DI and -DI
def up = change(high);
# down = -change(low)
# // Calculate parameter related to ADX, +DI and -DI
def down = -change(low);
# plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
# // Calculate parameter related to ADX, +DI and -DI
def plusDM = if na(up) then na else if (up > down and up > 0) then up else 0;
# minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)
# // Calculate parameter related to ADX, +DI and -DI
def minusDM = if na(down) then na else if (down > up and down > 0) then down else 0;
# trur = rma(tr, diLen)
# // Calculate parameter related to ADX, +DI and -DI
def trur = rma(tr(), diLen);
# plus = fixnan(100 * rma(plusDM, diLen) / trur)
# // Calculate Plus Directional Indicator (+DI)
def plus = fixnan(100 * rma(plusDM, diLen) / trur);
# minus = fixnan(100 * rma(minusDM, diLen) / trur)
# // Calculate Minus Directional Indicator (-DI)
def minus = fixnan(100 * rma(minusDM, diLen) / trur);
# sum = plus + minus
# // Calculate parameter related to ADX
def sum = plus + minus;
# adx = 100 * rma(abs(plus - minus) / (sum == 0 ? 1 : sum), adxLen)
# // Calculate Average Directional Index (ADX)
def adx = 100 * rma(absvalue(plus - minus) / (if sum == 0 then 1 else sum), adxLen);
#//======================================================================================================================
#//==================================================[Conditions]======================================================
# cndNa = na(atr) or na(adx) or na(plus) or na(minus) or na(atrMaLen)
# // Conditions for lack of sufficient data for calculations
def cndNa = (na(atr) or na(adx) or na(plus) or na(minus) or na(atrMaLen));
# cndSidwayss1 = useAtr and atr <= atrMa
# // Sideways Movement condition (based on ATR)
def cndSidwayss1 = useAtr and (atr <= atrMa);
#cndSidwayss2 = useAdx and adx <= adxLim
# // Sideways Movement condition (based on ADX)
def cndSidwayss2 = useAdx and (adx <= adxLim);
# cndSidways = cndSidwayss1 or cndSidwayss2
# // General Sideways Movement condition
def cndSidways = cndSidwayss1 or cndSidwayss2;
# cndUp = plus > minus
# // uptrend condition
def cndUp = plus > minus;
# cndDown = minus >= plus
# // downtrend condition
def cndDown = minus >= plus;
# trendType = cndNa ? na : cndSidways ? 0 : cndUp ? 2 : -2
# // Determine the type of trend
def trendType = if cndNa then na else if cndSidways then 0 else if cndUp then 2 else -2;
# smoothType = na(trendType) ? na : round(sma(trendType, smooth) / 2) * 2
# // Calculate the smoothed trend type oscillator
#def smoothType = if na(trendType) then na else (round(sma(trendType, smooth) / 2) * 2);
###input ma1_len = 11;
###input ma1_type = AverageType.EXPONENTIAL;
###def ma1 = MovingAverage(ma1_type, price, ma1_len);
def sma1 = MovingAverage(AverageType.simple, trendType, smooth);
def smoothType = if na(trendType) then na else (round(sma1 / 2) * 2);
#//======================================================================================================================
#//=========================================================[Drawing]=======================================================
# DefineGlobalColor("abc", CreateColor(128, 0, 128));
# GlobalColor("abc");
#colGreen30 = color.new(color.green, 30) // Define the color used in the drawings
#colGreen90 = color.new(color.green, 90) // Define the color used in the drawings
#colGray = color.new(color.gray, 20) // Define the color used in the drawings
#colWhite90 = color.new(color.white, 90) // Define the color used in the drawings
#colRed30 = color.new(color.red, 30) // Define the color used in the drawings
#colRed90 = color.new(color.red, 90) // Define the color used in the drawings
# https://www.tradingview.com/pine-script-reference/v4/#fun_color{dot}new
# color.new(color.red, 50)
# RETURNS
# Color with specified transparency.
# ARGUMENTS
# color (series[color])
# transp (input float) Possible values are from 0 (not transparent) to 100 (invisible).
DefineGlobalColor("colGreen30", color.green);
DefineGlobalColor("colGreen90", color.light_green);
DefineGlobalColor("colGray", color.gray);
DefineGlobalColor("colWhite90", color.white);
DefineGlobalColor("colred30", color.red);
DefineGlobalColor("colred90", color.light_red);
# band3 = plot(+3, title = "Band_3", color=color.black) // Draw the upper limit of the uptrend area
# band2 = plot(+1, title = "Band_2", color=color.black) // Draw the boundary between Sideways and Uptrend areas
# band1 = plot(-1, title = "Band_1", color=color.black) // Draw the boundary between Sideways and Downtrend areas
# band0 = plot(-3, title = "Band_0", color=color.black) // Draw the lower limit of the downtrend area
def lvl2 = 3;
def lvl1 = 1;
plot band3 = lvl2;
band3.SetDefaultColor(Color.black);
band3.setlineweight(1);
band3.hidebubble();
plot band2 = lvl1;
band2.SetDefaultColor(Color.black);
band2.setlineweight(1);
band2.hidebubble();
plot band1 = -lvl1;
band1.SetDefaultColor(Color.black);
band1.setlineweight(1);
band1.hidebubble();
plot band0 = -lvl2;
band0.SetDefaultColor(Color.black);
band0.setlineweight(1);
band0.hidebubble();
# fill(band2, band3, title = "Uptrend area", color = colGreen90) // Highlight the Uptrend area
# fill(band1, band2, title = "Sideways area", color = colWhite90) // Highlight the Sideways area
# fill(band0, band1, title = "Downtrend area", color = colRed90) // Highlight the Downtrend area
addcloud(lvl2, lvl1, GlobalColor("colGreen90"));
addcloud(-lvl1, -lvl2, GlobalColor("colred90"));
#var label lblUp = na
#label.delete(lblUp)
#lblUp := label.new(x = time, y = 2, text = "UP",
# color = color.new(color.green, 100), textcolor = color.black,
# style = label.style_label_left, xloc = xloc.bar_time,
# yloc = yloc.price, size=size.normal, textalign = text.align_left) // Show Uptrend area label
#var label lblSideways = na
#label.delete(lblSideways)
#lblSideways := label.new(x = time, y = 0, text = "SIDEWAYS",
# color = color.new(color.green, 100), textcolor = color.black,
# style = label.style_label_left, xloc = xloc.bar_time,
# yloc = yloc.price, size = size.normal, textalign = text.align_left) // Show Sideways area label
#var label lblDown = na
#label.delete(lblDown)
#lblDown := label.new(x = time, y = -2, text = "DOWN",
# color = color.new(color.green, 100), textcolor = color.black,
# style = label.style_label_left, xloc = xloc.bar_time,
# yloc = yloc.price, size = size.normal, textalign = text.align_left) // Show Downtrend area label
#var label lblCurrentType = na
#label.delete(lblCurrentType)
#lblCurrentType := label.new(x = time, y = smoothType,
# color = color.new(color.blue, 30), style = label.style_label_right,
# xloc = xloc.bar_time, yloc = yloc.price, size = size.small) // Show the latest status label
# trendCol = smoothType == 2 ? colGreen30 : smoothType == 0 ? colGray : colRed30
# // Determine the color of the oscillator in different conditions
# plot(smoothType, title = "Trend Type Oscillator", color = trendCol, linewidth = 3, offset = -lag, style = plot.style_stepline)
# // Draw the trend type oscillator
plot z = smoothtype;
z.AssignValueColor( if smoothType == 2 then globalcolor("colGreen30") else if smoothType == 0 then globalcolor("colGray") else globalcolor("colRed30"));
z.setlineweight(3);
z.hidebubble();
#