0% found this document useful (0 votes)
20 views10 pages

Dual Indicator

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views10 pages

Dual Indicator

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 10

//@version=5

indicator("Dual indicator", precision=0)

PhiSmoother(series float source, simple int length, simple float phase=3.7)=>


var array<float> coefs = na
var int length_1 = length - 1
var float W = 0.0
if na(coefs)
coefs := array.new<float>()
const float SQRT_PIx2 = math.sqrt(2.0 * math.pi)
const float MULTIPLIER = -0.5 / 0.93
var float length_2 = length * 0.52353
for int i=0 to length_1
float alpha = (i + phase - length_2) * MULTIPLIER
float beta = 1.0 / (0.2316419 * math.abs(alpha) + 1.0)
float phi = (math.exp(math.pow(alpha, 2) * -0.5)
*-0.398942280) * beta *
( 0.319381530 + beta *
(-0.356563782 + beta *
( 1.781477937 + beta *
(-1.821255978 + beta
* 1.330274429)))) + 1.011
if alpha < 0.0
phi := 1.0 - phi
float weight = phi / SQRT_PIx2
coefs.push(weight)
W += weight
float sma2 = math.avg(source, nz(source[1], source))
float E = 0.0
for int i=0 to length_1
E += coefs.get(i) * sma2[i]
E / W

ema(series float source, simple float length)=>


float alpha = 2.0 / (length + 1)
var float smoothed = na
smoothed := alpha * source + (1.0 - alpha) * nz(smoothed[1], source)

dema(series float source, simple float length)=>


float ema1 = ema(source, length)
float ema2 = ema( ema1, length)
2.0 * ema1 - ema2

tema(series float source, simple float length)=>


float ema1 = ema(source, length)
float ema2 = ema( ema1, length)
float ema3 = ema( ema2, length)
(ema1 - ema2) * 3.0 + ema3

wma(series float source, simple int length)=>


float weight_sum = length * 0.5 * (length + 1)
float sum = 0.0
for int i=0 to length - 1
sum += source[i] * (length - i)
sum / weight_sum

sma(series float source, simple int length)=>


float sum = ta.cum(source)
if bar_index < length - 1
sum / (bar_index + 1)
else
(sum - sum[length]) / length

filter(series float source,


simple int length,
simple float phase,
simple string style)=>
if length > 1
switch style
"PhiSmoother" => PhiSmoother(source, length, phase)
"EMA" => ema(source, length)
"DEMA" => dema(source, length)
"TEMA" => tema(source, length)
"WMA" => wma(source, length)
=> sma(source, length) // "SMA"
else
source

method get_score(series array<float> source)=>


array<float> scores = array.new<float>()
for int i=0 to source.size() - 1
float current = source.get(i)
int score_sum = 0
for j = 0 to source.size() - 1
float check = source.get(j)
int polarity = i < j ? 1 : -1
if i != j
if current > check
score_sum += polarity
else
score_sum -= polarity
scores.push(score_sum)
scores

method net_score(series array<float> scores)=>


int value = scores.size() - 1
float netScore = ((scores.avg() + value) / (value * 2.0) - 0.5) * 200.0
netScore

method get_color(series float score,


simple float transition_easing,
simple bool volatility_mode,
simple color rising_bullish,
simple color falling_bullish,
simple color falling_bearish,
simple color rising_bearish,
simple color rising_transition,
simple color falling_transition)=>
var color grad = na
float delta = score - nz(score[1], score)
color bullish = delta >= 0.0 ? rising_bullish : falling_bullish
color bearish = delta > 0.0 ? rising_bearish : falling_bearish
color transit = score > 0.0 ? (delta >= 0.0 ? rising_transition :
falling_transition)
: (delta >= 0.0 ? falling_transition :
rising_transition)
if volatility_mode
float easing = 0.01 * transition_easing
float crms = easing * math.sqrt(ta.cum(math.pow(math.abs(score), 2)) /
(bar_index + 1))
grad := if score > 0.0
transition_easing > 0.0 ? color.from_gradient(score, 0.0, crms,
transit, bullish) : bullish
else
transition_easing > 0.0 ? color.from_gradient(score, -crms, 0.0,
bearish, transit) : bearish
else
grad := if score > 0.0
transition_easing > 0.0 ? color.from_gradient(score, 0.0,
transition_easing, transit, bullish) : bullish
else
transition_easing > 0.0 ? color.from_gradient(score, -
transition_easing, 0.0, bearish, transit) : bearish
grad

string common = "Common Controls"


float source = input.source( close, "Source",
group=common)
string mode = input.string("Trend Strength", "Composite Cluster Mode",
group=common, options=["Trend Strength", "Volatility"], tooltip="Trend Strength
visualizes the directionality of the filter cluster. Volatility weights the score
to the bandwidth of the cluster.")
string filter = input.string( "PhiSmoother", "Cluster Filter",
group=common, options=["PhiSmoother", "EMA", "DEMA", "TEMA", "WMA", "SMA"],
tooltip="Choose a filter to build the moving average cluster with.")
float phase = input.float ( 3.7, "PhiSmoother Phase", group=common,
minval=0.0, step=0.1, tooltip="This allows for subtle adjustment (tweaking) of the
phase/lag for PhiSmoother")

string cluster = "Cluster Options"


int spacing = input.int(3, "Cluster Dispersion", group=cluster,
minval=1, maxval=10, tooltip="Choose the separation between the moving averages in
the cluster.")
int upper_trim = input.int(0, "Cluster Trim - Upper:", group=cluster,
inline="trim", minval=0, maxval=31)
int lower_trim = input.int(0, "Lower:", group=cluster, inline="trim",
minval=0, maxval=31, tooltip="The 'Upper' parameter modifies the shortest period of
the moving averages, whereas 'Lower' parameter adjusts the longest period.
Increasing the upper value reduces sensitivity, while increasing the lower value
heightens sensitivity.")

string output = "Composite Post Smoothing"


string post_smooth_filt = input.string("PhiSmoother", "PostSmooth - Filter:",
group=output, inline="post", options=["PhiSmoother", "EMA", "DEMA", "TEMA", "WMA",
"SMA"])
int post_smooth_len = input.int ( 1, "Length:",
group=output, inline="post", minval=1, tooltip="Period of the cluster's post
smoothing.")

string signal = "Composite Signal Settings"


string signal_filter = input.string("PhiSmoother", "Signal - Filter:",
group=signal, inline="signal", options=["PhiSmoother", "EMA", "DEMA", "TEMA",
"WMA", "SMA"])
int signal_length = input.int ( 20, "Length:", group=signal,
inline="signal", minval=1, tooltip="Period of the momentum signal plot.")
color signal_color = input.color ( color.white, "Filter Color",
group=signal)

string threshold = "Threshold Levels"


float upperLevel = input.float( 75.00, "Levels - Upper:", group=threshold,
inline="level", minval= 1.0, maxval=99.0, step=2.0)
float lowerLevel = input.float(-75.00, "Lower:", group=threshold,
inline="level", minval=-99.0, maxval=-1.0, step=2.0, tooltip="Fine-tune the
thresholds to your liking")

string colors = "Coloring Preferences"


//bool candle_color = input.bool ( false, "Candle Coloring",
group=colors)
float transition_easing = input.float( 50.0, "Transition Easing",
group=colors, maxval= 100.0, minval=0.0, step=5.0, tooltip="Adjust the sensitivity
to ranging conditions.")
bool fill_bg = input.bool ( true, "Fill Background", group=colors,
inline= "fill")
int fill_alpha = input.int ( 85, "",
group=colors, inline= "fill", minval=0, maxval=100)
color rising_bullish = input.color(#FFCC00, "Bullish Color", group=colors,
inline= "bull")
color rising_transition = input.color(#9598A1, "Transition Color",
group=colors, inline="range")
color falling_bearish = input.color(#5500CC, "Bearish Color", group=colors,
inline= "bear")

var bool VOLATILITY_MODE_ON = mode == "Volatility"

price = input(title='Source', defval=close)


alpha = input.int(title='Combined Smoothness', defval=15, minval=1)

array<float> filter_cluster = array.new<float>(34)


filter_cluster.set( 0, source)
filter_cluster.set( 1, filter(source, spacing, phase, filter))
filter_cluster.set( 2, filter(source, 2 * spacing, phase, filter))
filter_cluster.set( 3, filter(source, 3 * spacing, phase, filter))
filter_cluster.set( 4, filter(source, 4 * spacing, phase, filter))
filter_cluster.set( 6, filter(source, 5 * spacing, phase, filter))
filter_cluster.set( 7, filter(source, 6 * spacing, phase, filter))
filter_cluster.set( 8, filter(source, 7 * spacing, phase, filter))
filter_cluster.set( 9, filter(source, 8 * spacing, phase, filter))
filter_cluster.set(10, filter(source, 9 * spacing, phase, filter))
filter_cluster.set(11, filter(source, 10 * spacing, phase, filter))
filter_cluster.set(12, filter(source, 11 * spacing, phase, filter))
filter_cluster.set(13, filter(source, 12 * spacing, phase, filter))
filter_cluster.set(14, filter(source, 13 * spacing, phase, filter))
filter_cluster.set(15, filter(source, 14 * spacing, phase, filter))
filter_cluster.set(16, filter(source, 15 * spacing, phase, filter))
filter_cluster.set(17, filter(source, 16 * spacing, phase, filter))
filter_cluster.set(18, filter(source, 17 * spacing, phase, filter))
filter_cluster.set(19, filter(source, 18 * spacing, phase, filter))
filter_cluster.set(20, filter(source, 19 * spacing, phase, filter))
filter_cluster.set(21, filter(source, 20 * spacing, phase, filter))
filter_cluster.set(22, filter(source, 21 * spacing, phase, filter))
filter_cluster.set(23, filter(source, 22 * spacing, phase, filter))
filter_cluster.set(24, filter(source, 23 * spacing, phase, filter))
filter_cluster.set(25, filter(source, 24 * spacing, phase, filter))
filter_cluster.set(26, filter(source, 25 * spacing, phase, filter))
filter_cluster.set(27, filter(source, 26 * spacing, phase, filter))
filter_cluster.set(28, filter(source, 27 * spacing, phase, filter))
filter_cluster.set(29, filter(source, 28 * spacing, phase, filter))
filter_cluster.set(30, filter(source, 29 * spacing, phase, filter))
filter_cluster.set(31, filter(source, 30 * spacing, phase, filter))
filter_cluster.set(32, filter(source, 31 * spacing, phase, filter))
filter_cluster.set(33, filter(source, 32 * spacing, phase, filter))

if upper_trim > 0
for int i=0 to math.min(upper_trim - 1, filter_cluster.size() - 1)
if filter_cluster.size() > 2
filter_cluster.shift()
else
break
if lower_trim > 0
for int i=0 to math.min(lower_trim - 1, filter_cluster.size() - 1)
if filter_cluster.size() > 2
filter_cluster.pop()
else
break

float ribbon_max = filter_cluster.max()


float ribbon_min = filter_cluster.min()
float ribbon_width = ribbon_max - ribbon_min
float ribbon_rank = VOLATILITY_MODE_ON ? nz(ribbon_width / math.avg(ribbon_max,
ribbon_min)) : 1

array<float> score = filter_cluster.get_score()


float net_score = filter(score.net_score() * ribbon_rank, post_smooth_len, 3.7,
post_smooth_filt)
float signal_value = signal_length < 2 ? na : filter(ta.sma(net_score, 2),
signal_length, 3.7, signal_filter)

top = hline(VOLATILITY_MODE_ON ? na : 100.0, "Top", #FF0000)


upper = hline(VOLATILITY_MODE_ON ? na : upperLevel, "+Level", rising_bullish,
hline.style_dotted, 2)
center = hline( 0.0, "Center", #CCCCCC)
lower = hline(VOLATILITY_MODE_ON ? na : lowerLevel, "+Level", falling_bearish,
hline.style_dotted, 2)
bottom = hline(VOLATILITY_MODE_ON ? na : -100.0, "Bottom", #00FF00)
const color invisible = #00000000
fill( top, upper, 100.0, upperLevel, #800000, invisible)
fill(center, upper, upperLevel, 0.0, color.new( rising_bullish, 100),
color.new(rising_bullish, fill_bg ? fill_alpha : 100))
fill(center, lower, 0.0, lowerLevel, color.new(falling_bearish, fill_bg ?
fill_alpha : 100), color.new(falling_bearish, 100))
fill(bottom, lower, lowerLevel, -100.0, invisible, #008000)

//barcolor(candle_color ? main_color : na)

color1 = net_score>signal_value ? #00FF00 : #ff0000

net = plot(net_score, "Score", color1, 3)


zero = plot( 0.0, "", invisible)
plot(signal_value, "Signal", signal_color, 1)
fill(net, zero, net_score > 0.0 ? net_score : 0.0,
net_score > 0.0 ? 0.0 : net_score,
net_score > 0.0 ? color.new(rising_bullish, fill_bg and
VOLATILITY_MODE_ON ? fill_alpha : 100) : color.new(falling_bearish, 100),
net_score > 0.0 ? color.new(rising_bullish, 100) :
color.new(falling_bearish, fill_bg and VOLATILITY_MODE_ON ? fill_alpha : 100))

//===============================================
f_LazyLine(_data, _length) =>
w1 = 0
w2 = 0
w3 = 0
L1 = 0.0
L2 = 0.0
L3 = 0.0
w = _length / 3

if _length > 2
w2 := math.round(w)
w1 := math.round((_length - w2) / 2)
w3 := int((_length - w2) / 2)

L1 := ta.wma(_data, w1)
L2 := ta.wma(L1, w2)
L3 := ta.wma(L2, w3)
L3
else
L3 := _data
L3
L3
//====================================

LL = f_LazyLine(price, alpha)

c_up = color.new(#33ff00, 0)
c_dn = color.new(#ff1111, 0)
uptrend = LL > LL[1]

plot(LL, 'SS_WMA Line', color=uptrend ? c_up : c_dn,


linewidth=3,force_overlay=true)
plot(ta.wma(price, alpha), 'WMA', color=color.new(color.purple, 0),
display=display.none,force_overlay=true)

//
===================================================================================
=====================================
// v2: add optional up/dn arrow signal on change of direction (swing)
ShowSig = input(title='Up/Dn Swing Signal?', defval=false)
SigMulti = input.float(title='Signal Locator %', defval=1.0, step=0.2, minval=0,
maxval=20)

SignalOn = ShowSig and barstate.isconfirmed // ensure the signal plots *only*


after "the bar closes" :) -- insert jokes :)
SwingDn = uptrend[1] and not uptrend
SwingUp = uptrend and not uptrend[1]

d = SigMulti / 100 * LL //we'll use this to tweak a good location for the signal
(that is not tied to price-specific parameters)

plotshape(SignalOn and SwingDn ? LL + d : na, title='Swing Down',


style=shape.triangledown, location=location.absolute, size=size.small,
color=c_dn,force_overlay=true)
plotshape(SignalOn and SwingUp ? LL - d : na, title='Swing Up',
style=shape.triangleup, location=location.absolute, size=size.small,
color=c_up,force_overlay=true)

//
===================================================================================
=====================================
// v3: enable alerts

// need to use alertcondition() to support variable resolution


alertcondition(SwingUp, 'Swing Up', 'Swing Up Detected!') // explicit swing up
alertcondition(SwingDn, 'Swing Down', 'Swing Down Detected!') // explicit swing
down
alertcondition(SwingUp or SwingDn, 'Swing', 'Up/Down Swing Detected!') // either
swings
//
// This source code is subject to the terms of the Mozilla Public License 2.0 at
https://mozilla.org/MPL/2.0/
// © EzAlgo

//@version=5
//indicator("EzTrendlines ++",overlay = false)

//inputs
show_trendlines = input.bool(true, 'Show Trendlines', inline =
'tl_1',group='Trendlines')
upper_trendline_color = input.color(#9598a1, '', inline =
'tl_1',group='Trendlines')
lower_trendline_color = input.color(#9598a1, '', inline =
'tl_1',group='Trendlines')
extendLine = input.bool(true, 'Extend', inline = 'tl_1',group='Trendlines')

linestyle_curr_inp = input.string(defval = 'Solid', title = "Style", options =


['Solid', 'Dotted', 'Dashed'],inline = "tl_3",group='Trendlines')
line_width_curr = input.int(1, 'Width', step = 1, minval = 1,maxval =
4,inline = "tl_3",group='Trendlines')

pivLen_L = input.int(20, 'Lookback', step = 1, minval = 1, inline


='tl_5',group='Trendlines')
pivLen_R = pivLen_L//input.int(20, '/', step = 1, minval = 1, inline
='tl_5',group='Trendlines')

hideCrossed = not(input.bool(true, 'Show Broken', inline =


'tl_2',group='Trendlines'))
broken_color_up = input.color(#9598a1, '', inline =
'tl_2',group='Trendlines')
broken_color_down = input.color(#9598a1, '', inline =
'tl_2',group='Trendlines')
extendLine_B = input.bool(true, 'Extend', inline = 'tl_2',group='Trendlines')
show_signals = input.bool(true, 'Show Signals', inline =
'tl_s',group='Trendlines')
broken_color_up_signal = input.color(color.green, '', inline =
'tl_s',group='Trendlines')
broken_color_down_signal = input.color(color.red, '', inline =
'tl_s',group='Trendlines')

maxLines = input.int(3, 'Max Broken', step = 1, minval = 1, maxval = 50,


inline = 'tl_2_B',group='Trendlines')
Source_tl = input.string('Close', 'Mitigation', options = ['Close',
'High/Low'], inline ='tl_2_B',group='Trendlines')

linestyle_broken_inp = input.string(defval = 'Solid', title = "Style (Broken)",


options = ['Solid', 'Dotted', 'Dashed'],inline = "tl_2-1",group='Trendlines')
line_width_broken = input.int(2, 'Width', step = 1, minval = 1,maxval =
4,inline = "tl_2-1",group='Trendlines')

lineStyle_curr= linestyle_curr_inp == 'Solid' ? line.style_solid :


linestyle_curr_inp == 'Dotted' ? line.style_dotted : line.style_dashed
lineStyle_broken= linestyle_broken_inp == 'Solid' ? line.style_solid :
linestyle_broken_inp == 'Dotted' ? line.style_dotted : line.style_dashed

s_close = request.security(ticker.standard(syminfo.tickerid), timeframe.period,


close)
s_open = request.security(ticker.standard(syminfo.tickerid), timeframe.period,
open)
s_high = request.security(ticker.standard(syminfo.tickerid), timeframe.period,
high)
s_low = request.security(ticker.standard(syminfo.tickerid), timeframe.period, low)

var line[] pivot_high_array = array.new_line(),var line[] pivot_low_array =


array.new_line()
ph_M = ta.pivothigh(s_high, pivLen_L, pivLen_R)
pl_M = ta.pivotlow(s_low, pivLen_L, pivLen_R)
ph = ta.pivothigh(s_high, pivLen_L, pivLen_R)
pl = ta.pivotlow(s_low, pivLen_L, pivLen_R)

var float prev_close_H = na, var float curr_close_H = na


var float prev_close_L = na, var float curr_close_L = na

var int X_prev_low = na, var float Y_prev_low = na, var int X_curr_low = na, var
float Y_curr_low = na
var int X_curr_high = na, var float Y_curr_high = na, var int X_prev_high = na, var
float Y_prev_high = na

maxLines := hideCrossed ? 0 : maxLines


tl_array_size_up = maxLines/2
tl_array_size_dn = maxLines%2==0? maxLines/2 : (maxLines/2)+1

//functions

newTrendLine(ptype, x1, y1, x2, y2)=>


new_trendline = line.new(x1, y1, x2, y2, extend = extendLine ? extend.right :
extend.none, color = ptype == 'ph' ? upper_trendline_color : lower_trendline_color,
width = line_width_curr,style = lineStyle_curr,xloc = xloc.bar_index, force_overlay
= true)
if ptype == 'ph'
pivot_high_array.unshift(new_trendline)
else
pivot_low_array.unshift(new_trendline)

SlopeOfLine(line)=>
slopePh = (line.get_y2(line) - line.get_y1(line))/(line.get_x2(line) -
line.get_x1(line))
extendedPh = line.get_y2(line) - slopePh * (line.get_x2(line) - bar_index)
extendedPh

up_trend_line_formed= false
down_trend_line_formed = false

if pl
X_prev_low := X_curr_low, Y_prev_low := Y_curr_low, prev_close_L :=
curr_close_L
X_curr_low := bar_index[pivLen_R], Y_curr_low := s_low[pivLen_R],
curr_close_L:= s_close[pivLen_R]
if Y_prev_low < Y_curr_low and show_trendlines and Y_curr_low > prev_close_L
newTrendLine('pl', X_prev_low, Y_prev_low, X_curr_low, Y_curr_low)
down_trend_line_formed:=true

if ph
X_prev_high := X_curr_high, Y_prev_high := Y_curr_high, prev_close_H :=
curr_close_H
X_curr_high := bar_index[pivLen_R], Y_curr_high := s_high[pivLen_R],
curr_close_H:= s_close[pivLen_R]

if Y_prev_high > Y_curr_high and show_trendlines and prev_close_H > Y_curr_high


newTrendLine('ph', X_prev_high, Y_prev_high, X_curr_high, Y_curr_high)
up_trend_line_formed := true

if close > Y_prev_high


Y_prev_high:=0.000000

if close < Y_prev_low


Y_prev_low:= 9999999999.9999

// alertcondition(up_trend_line_formed,'Up TrendLine Formed','Up TrendLine Formed')


// alertcondition(down_trend_line_formed,'Down TrendLine Formed','Down TrendLine
Formed')
alertcondition(down_trend_line_formed or up_trend_line_formed,'Trendline
Formed','Trendline Formed')

up_trend_line_broken = false
down_trend_line_broken = false

for x in pivot_low_array
var line [] Down_Trend_Lines = array.new_line(tl_array_size_up)
var label [] Down_Trend_Labels = array.new_label(tl_array_size_up)
src = Source_tl == 'Close' ? s_close : s_low
x.set_xy2(bar_index, SlopeOfLine(x))
if x.get_x2() - x.get_x1() > 300
x.delete()
if src < line.get_y2(x)
tl_line = line.new(line.get_x1(x), line.get_y1(x), line.get_x2(x),
line.get_y2(x), color = broken_color_down, style = lineStyle_broken, width =
line_width_broken,xloc = xloc.bar_index, extend = extendLine_B ? extend.right :
extend.none,force_overlay = true)
down_trend_line_broken:=true
Down_Trend_Lines.unshift(tl_line)
line.delete(x)
if Down_Trend_Lines.size() > (tl_array_size_up)
line.delete(Down_Trend_Lines.pop())

for x in pivot_high_array
var line [] Up_Trend_Lines = array.new_line(tl_array_size_dn)
var label [] Up_Trend_Labels = array.new_label(tl_array_size_dn)
src = Source_tl == 'Close' ? s_close : s_high
x.set_xy2(bar_index, SlopeOfLine(x))
if x.get_x2() - x.get_x1() > 300
x.delete()
if src > line.get_y2(x)
tl_line = line.new(line.get_x1(x), line.get_y1(x), line.get_x2(x),
line.get_y2(x), color = broken_color_up, style = lineStyle_broken, width =
line_width_broken,xloc = xloc.bar_index, extend = extendLine_B ? extend.right :
extend.none, force_overlay = true)
up_trend_line_broken:=true
Up_Trend_Lines.unshift(tl_line)
line.delete(x)
if Up_Trend_Lines.size() > (tl_array_size_dn)
line.delete(Up_Trend_Lines.pop())

plotshape(show_signals and up_trend_line_broken? low : na, title='Trendline Broken


Up', style=shape.xcross, textcolor=color.new(color.white, 0), size=size.small,
location=location.belowbar, color=broken_color_up_signal,display= display.all -
display.status_line, editable = false, force_overlay = true)
plotshape(show_signals and down_trend_line_broken? high : na, title='Trendline
Broken Down', style=shape.xcross, textcolor=color.new(color.white, 0),
size=size.small, location=location.abovebar,
color=broken_color_down_signal,display= display.all - display.status_line,
editable = false, force_overlay = true)

// alertcondition(up_trend_line_broken,'Up TrendLine Broken','Up TrendLine Broken')


// alertcondition(down_trend_line_broken,'Down TrendLine Broken','Down TrendLine
Broken')
alertcondition(up_trend_line_broken or down_trend_line_broken,'Trendline
Broken','Trendline Broken')

You might also like