0% found this document useful (0 votes)
12 views48 pages

Serum Indicator

This document contains a Pine Script™ code for a trading indicator called 'ꜱᴇʀᴜᴍ ᴛᴏᴏʟᴋɪᴛ [ꜱᴛ]', which is designed to analyze market trends and generate buy/sell signals based on various calculations including CCI, ATR, and moving averages. The script includes customizable settings for signal display, color coding, and trading strategies, allowing users to adjust parameters for short-term and reversal signals. It also incorporates volume analysis and plots to visualize trading signals on the TradingView platform.

Uploaded by

Mkil Gopal
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)
12 views48 pages

Serum Indicator

This document contains a Pine Script™ code for a trading indicator called 'ꜱᴇʀᴜᴍ ᴛᴏᴏʟᴋɪᴛ [ꜱᴛ]', which is designed to analyze market trends and generate buy/sell signals based on various calculations including CCI, ATR, and moving averages. The script includes customizable settings for signal display, color coding, and trading strategies, allowing users to adjust parameters for short-term and reversal signals. It also incorporates volume analysis and plots to visualize trading signals on the TradingView platform.

Uploaded by

Mkil Gopal
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/ 48

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.

0
at https://mozilla.org/MPL/2.0/
// © SerumTechnology

//@version=5
indicator('ꜱᴇʀᴜᴍ ᴛᴏᴏʟᴋɪᴛ [ꜱᴛ]', overlay=true, precision = 2, linktoseries = true,
max_bars_back = 5000, max_lines_count = 500, max_boxes_count = 500,
max_labels_count = 500)
import TradingView/ta/7

// VARIBLES GENRERALES

fuenteclose = close
fuenteopen = open
fuentehigh = high
fuentelow = low
fuentevolume = volume

bool truevar = true


bool falsevar = false

//FUNCIONES GENRERALES

tdFunction(int tdx) =>


cci = ta.cci(close, 3)
cciL = ta.valuewhen(cci > -300, cci, 1)
uppval = ta.highest(tdx)
dnval = ta.lowest(tdx)

dntd = uppval
uptd = dnval

if cci >= 0 and cciL < 0


uptd := dntd[1]
if cci <= 0 and cciL > 0
dntd := uptd[1]

if cci >= 0
if uptd < uptd[1]
uptd := uptd[1]
else
if cci <= 0
if dntd > dntd[1]
dntd := dntd[1]

float td = 0.
td := cci >= 0 ? uptd : cci <= 0 ? dntd : td[1]
td

oscfun(int s, int u , int per) =>


sval = s
uval = u

// Calcular xHMU y xLMD


xHMU = math.max(close - close[1], 0)
xLMD = math.max(close[1] - close, 0)

// Calcular xPrice y xPriceAbs


xPrice = ta.wma(xHMU - xLMD, 2)// xHMU - xLMD //
xPriceAbs = math.abs(xPrice)

// Calcular xuXA y xuXAAbs


xuXA = ta.ema(ta.ema(ta.wma(xPrice, per), s), u)
xuXAAbs = ta.ema(ta.ema(ta.wma(xPriceAbs, per), s), u)

// Calcular el DTI
Val1 = 100*xuXA
Val2 = xuXAAbs
DTI_rawx = Val2 != 0 ? Val1 / Val2 : 0
DTI_raw = DTI_rawx * 0.96

// Normalizar el DTI para que oscile entre 0 y 100


osc = (DTI_raw + 100) / 2
osc

//------------------------LONG / SHORT
ZONES----------------------------------------------------

color bullZone = input.color(#29fff8, title = 'Buy', inline = "LSZone", group =


'======>> Signal Settings <<======')
color bearZone = input.color(#ff298d, title = 'Sell', inline = "LSZone", group =
'======>> Signal Settings <<======')
bool showSignals = input.bool(truevar, 'Signals mode', inline = "Signals", group =
'======>> Signal Settings <<======')
string signalmode = input.string('Buy / Sell', '', options = ['Buy / Sell',
'Reversal'], inline = "Signals", group = '======>> Signal Settings <<======')
string signalsize = input.string(defval = 'Small',
title = '',
options = ['Tiny', 'Small', 'Normal', 'Large', 'huge'],
inline = 'Signals',
group = '======>> Signal Settings <<======')

signaltextZise = signalsize == 'Tiny' ? size.tiny :


signalsize == 'Small' ? size.small :
signalsize == 'Normal' ? size.normal :
signalsize == 'Large' ? size.large :
size.huge
bool showBar = input.bool(truevar, 'Bar Coloring', inline = "colormode", group =
'======>> Signal Settings <<======')
string colormode = input.string('Gradient', '', ['Normal', 'Gradient'], inline =
"colormode", group = '======>> Signal Settings <<======')

//
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▄ ▄ ▄ ▄ ▄ ▄ ▄ ▄ ▄
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒
//
SHORT TERM SIGNALS
//
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▄ ▄ ▄ ▄ ▄ ▄ ▄ ▄ ▄
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒

//-------------------------------------
vstop----------------------------------------------------------------------------

//input variables
//int LengthV= 2 //input.int(title="Look Back Period", defval=3)
int ATRPeriodV= 6 //input.int(title="ATR Period", defval=7)
int MultV= input.int(18, title = 'Sensitivity', minval = 5, step = 1, inline =
'short-term inputs', group = '--- Buy / Sell')
bool showClassifier = input.bool(true, title = 'Classifier', inline = 'cl', group =
'--- Buy / Sell')
bool showtsShortTerm = input.bool(true, title = 'Trailing Stop', inline = 'ts',
group = '--- Buy / Sell')
color tsColorbull = input.color(color.new(#29fff8, 20), title = '', inline = 'ts',
group = '--- Buy / Sell')
color tsColorbear = input.color(color.new(#ff298d, 20), title = '', inline = 'ts',
group = '--- Buy / Sell')
bool showtpShortTerm = input.bool(true, title = 'Take Profit', inline = 'tp', group
= '--- Buy / Sell')
color showtpColor = input.color(#ffffff, title = '', inline = 'tp', group = '---
Buy / Sell')

tbullts = color.t(tsColorbull)
tbearts = color.t(tsColorbear)

//================================================================
int reversens = input.int(12, title = 'Sensitivity', minval = 5, step = 1, group =
'--- Reversal')

tdsignal = tdFunction(1)

// Calcular valores de stop


short_stop = tdsignal + (MultV / 10) * ta.atr(ATRPeriodV)
long_stop = tdsignal - (MultV / 10) * ta.atr(ATRPeriodV)

var float shortvs = 0.


var float longvs = 0.
var int direction = 0

if na(shortvs)
shortvs := short_stop
else
shortvs := close > shortvs ? short_stop : math.min(short_stop, shortvs[1])

if na(longvs)
longvs := long_stop
else
longvs := close < longvs ? long_stop : math.max(long_stop, longvs[1])
// Actualizar dirección
direction := na(direction[1]) ? 0 :
(direction[1] <= 0 and close >= shortvs[1] ? 1 :
(direction[1] >= 0 and close <= longvs[1] ? -1 : direction[1]))

var float pc = 0.
var color colorts = na

switch
direction > 0 =>
pc := longvs
colorts := tsColorbull
direction < 0 =>
pc := shortvs
colorts := tsColorbear
=>
pc := 0.
colorts := na

atrbull = longvs + ta.atr(18) * 0.236


atrbear = shortvs - ta.atr(18) * 0.236

pcfill = direction > 0 ? atrbull : atrbear

color colortsfill = pc != 0.? direction > 0 ? color.from_gradient(ta.ema(close, 6),


longvs, shortvs, color.new(tsColorbull, tbullts + 10), color.new(tsColorbull,
tbullts + 95)) :
color.from_gradient(ta.ema(close, 6), longvs, shortvs,
color.new(tsColorbear, tbearts + 95), color.new(tsColorbear, tbearts + 10)) : na

plotts = plot(showtsShortTerm and pc != 0.0 ? pc : na, color = colorts, editable =


false, display = display.pane )
plottsfill = plot(showtsShortTerm? pcfill : na, color = na, editable = false,
display = display.pane )

fill(plotts, plottsfill, color = colortsfill)

//----------------------------------------------volumen
extra-----------------------------------------------

//volsignal = volume
emaVol = nz(ta.ema(fuentevolume, 200), volume +100)

volConfirm = fuentevolume>= emaVol


noPlus = fuentevolume < emaVol

var volstate = 0
if volConfirm
volstate := 1
if noPlus
volstate := 2
//--------------------------------------------
Classifier--------------------------------

src = ohlc4

angle(_src) =>
rad2degree=180/3.14159265359
ang=rad2degree*math.atan((_src[0] - _src[1])/ta.atr(14))

ma = ta.ema(src, 30)
fil1 = angle(ma)

fil2 = tdFunction(3)
//fil2b = tdFunction(2)

fil3 = oscfun(10, 1, 14)


fil4 = ta.alma(fil3, 6, 0.85, 6)

var int fil2state = 0


fil2state := fil2>fil2[1] ? 1 : fil2 < fil2[1] ? 2 : nz(fil2state[1])

var int fil4state = 0


fil4state := fil3 > fil4 ? 1 : fil3 < fil4 ? 2 : nz(fil4state[1])

var int long1 = 0


long1 := fil1 >= 2 ? 1 : 0
var int long2 = 0
long2 := fil2state == 1 ? 1 : 0
var int long3 = 0
long3 := fil3 >= 50 ? 1 : 0
var int long4 = 0
long4 := fil4state == 1 ? 1 : 0

longClassint = long1 + long2 + long3 + long4


longClass = str.tostring(longClassint)

var int short1 = 0


short1 := fil1 <= -2 ? 1 : 0
var int short2 = 0
short2 := fil2state == 2 ? 1 : 0
var int short3 = 0
short3 := fil3 < 50 ? 1 : 0
var int short4 = 0
short4 := fil4state == 2 ? 1 : 0

shortClassint = short1 + short2 + short3 + short4


shortClass = str.tostring(shortClassint)

//
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▄ ▄ ▄ ▄ ▄ ▄ ▄ ▄
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒
//
REVERSAL SIGNALS
//
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▄ ▄ ▄ ▄ ▄ ▄ ▄ ▄
▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒

//-----------------------------------------------------PLOTS AND BAR


COLOR---------------------------------------------

//--------------------------------------SHORT TERM-----------------------------

//general conditions
longer = direction > 0
shorter = direction < 0

var int shortstatus2 = 0

if longer
shortstatus2 := 1
if shorter
shortstatus2 := 2

//---------------------take profit

osc = oscfun(3, 2, 14)

bullTP = (ta.crossover(osc, 80) or ta.crossover(osc, 90) or ta.crossover(osc, 95))


and showtpShortTerm and shortstatus2 == 1 and signalmode == 'Buy / Sell' and not
(shortstatus2 == 1 and shortstatus2[1] == 2)
bearTP = (ta.crossunder(osc, 20) or ta.crossunder(osc, 10) or ta.crossunder(osc,
5)) and showtpShortTerm and shortstatus2 == 2 and signalmode == 'Buy / Sell' and
not (shortstatus2 == 2 and shortstatus2[1] == 1)

if bullTP and barstate.isconfirmed


label.new(bar_index, high, "✖", style=label.style_label_down, color=
color.new(color.green, 100), textcolor=showtpColor, size = size.tiny)

if bearTP and barstate.isconfirmed


label.new(bar_index, low, "✖", style=label.style_label_up,
color=color.new(color.red, 100), textcolor=showtpColor, size = size.tiny)

textbull = shortstatus2 == 1 and volConfirm ? '▲✚' : '▲'


textbear = shortstatus2 == 2 and volConfirm ? '▼✚' : '▼'
buycondshortterm = shortstatus2 == 1 and shortstatus2[1] == 2 and signalmode ==
'Buy / Sell'
sellcondshortterm = shortstatus2 == 2 and shortstatus2[1] == 1 and signalmode ==
'Buy / Sell'
barColor = shortstatus2 == 1? color.from_gradient(ta.ema(close, 3), atrbull,
atrbear[2], color.new(#ffffff, 10), bullZone) : color.from_gradient(ta.ema(close,
3), atrbull[2], atrbear, bearZone, color.new(#ffffff, 10))

if buycondshortterm and showSignals


//label.new(bar_index, pc, text = textbull, color = bullZone, style =
label.style_label_up, textcolor=color.new(#000000, 0), size = size.small)
label.new(bar_index, pc, text = showClassifier ? longClass : textbull, color =
bullZone, style = label.style_label_up, textcolor=color.new(#000000, 0), size =
signaltextZise)

if sellcondshortterm and showSignals


label.new(bar_index, pc, text = showClassifier ? shortClass : textbear, color =
bearZone, style = label.style_label_down, textcolor=color.new(#000000, 0), size =
signaltextZise)

barcoloredShortTerm = showBar and shortstatus2 == 1 and longer? color.new(bullZone,


0) :
showBar and shortstatus2 == 1 and not longer? color.new(bullZone,
35) :
showBar and shortstatus2 == 2 and shorter? color.new(bearZone, 0) :
showBar and shortstatus2 == 2 and not shorter? color.new(bearZone, 35)
: not showBar ? na :color.new(color.white, 30)

//--------------------------------Reversal Signals

oscrev = oscfun(3, 2, reversens)

emasmoth = ta.alma(oscrev, 6, 0.85, 6)

longre = ta.crossover(oscrev, emasmoth) and oscrev <=40 and oscrev > 20


longreplus = ta.crossover(oscrev, emasmoth) and oscrev <=20
shortre = ta.crossunder(oscrev, emasmoth) and oscrev >= 60 and oscrev < 80
shortreplus = ta.crossunder(oscrev, emasmoth) and oscrev > 80

var int reversstatus = 0

if ta.crossover(oscrev, emasmoth) and oscrev <=40


reversstatus := 1
if ta.crossunder(oscrev, emasmoth) and oscrev >= 60
reversstatus := 2

// Cálculo del desplazamiento vertical basado en el ATR


int atrPeriods = 14
atrL = ta.atr(atrPeriods)
labelYOffset = atrL * 1.5
shortpos = (close+labelYOffset) < high? high : close+labelYOffset
longpos = (close-labelYOffset) > low? low : close-labelYOffset

longreverstext = longreplus? '▲✚' : '▲'


shortreverstext = shortreplus? '▼✚' : '▼'

if (longre or longreplus) and showSignals and signalmode == 'Reversal'


label.new(bar_index, longpos, text = longreverstext, color = bullZone, style =
label.style_label_up, textcolor=color.new(#000000, 0), size = size.small)

if (shortre or shortreplus) and showSignals and signalmode == 'Reversal'


label.new(bar_index, shortpos, text = shortreverstext, color = bearZone, style
= label.style_label_down, textcolor=color.new(#000000, 0), size = size.small)

coloreobarrevers = color.from_gradient(oscrev, 10, 90, bullZone, bearZone)

coloreadoRevesal = showBar and reversstatus == 1 ? color.new(bullZone, 0) :


showBar and reversstatus == 2 ? color.new(bearZone, 0) :
not showBar ? na : color.new(color.white, 30)

//------------------------COLOREADO DE BARRAS---------------------------------
barcolor(signalmode == 'Buy / Sell' and colormode == 'Normal' and showBar?
barcoloredShortTerm :
signalmode == 'Buy / Sell' and colormode == 'Gradient' and showBar?
barColor :
signalmode == 'Reversal' and colormode == 'Normal' and showBar?
coloreadoRevesal :
signalmode == 'Reversal' and colormode == 'Gradient' and showBar?
coloreobarrevers : not showBar? na : color.new(color.white, 50) , editable =
falsevar)

// TREND DIRECTION

tdtrenddash = tdFunction(2)
var float trackdash = 0.
trackdash := tdtrenddash > tdtrenddash[1] ? 1 : tdtrenddash < tdtrenddash[1] ? 2 :
trackdash[1]

emaFast = ta.ema(close, 10)


emaSlow = ta.ema(close, 55)

var emastate = 0
if emaFast >= emaSlow
emastate := 1
if emaFast < emaSlow
emastate := 2

//trendStrength = math.abs(emaFast - emaSlow) / close * 1000

trenddashtext = emastate == 1 and tdtrenddash > tdtrenddash[1] ? 'ʙᴜʟʟɪꜱʜ' :


(emastate ==1 and (tdtrenddash == tdtrenddash[1] or tdtrenddash <
tdtrenddash[1])) or (emastate ==2 and (tdtrenddash == tdtrenddash[1] or tdtrenddash
> tdtrenddash[1]))? 'ʀᴀɴɢɪɴɢ' :
emastate == 2 and tdtrenddash < tdtrenddash[1] ? 'ʙᴇᴀʀɪꜱʜ' : na
if na(trenddashtext)
trenddashtext:= emaFast < close and tdtrenddash > tdtrenddash[1]? 'ʙᴜʟʟɪꜱʜ' :
emaFast > close and tdtrenddash < tdtrenddash[1]? 'ʙᴇᴀʀɪꜱʜ' : 'ʀᴀɴɢɪɴɢ'

trenddashcolor = emastate == 1 or (na(emaSlow) and close>emaFast)?


color.new(bullZone, 50) :
emastate == 2 or (na(emaSlow) and close<emaFast)?
color.new(bearZone, 50) : na

//-----------------------------------------------
VOLATILIDAD------------------------------------------------

//Calculates Volatility for Dashboard


atrV = ta.atr(14)
stdAtr = 2 * ta.stdev(atrV, 20)
smaAtr = ta.wma(atrV, 20)
topAtrDev = smaAtr + stdAtr
bottomAtrDev = smaAtr - stdAtr
calcDev = (atrV - bottomAtrDev) / (topAtrDev - bottomAtrDev)
percentVol = (40 * calcDev + 15)

getDynamicLength(maxLength) =>
math.min(maxLength, bar_index + 1)

_RMA(float src, int length) =>


len = getDynamicLength(length)
var float rma = na
rma := na(rma) ? src : (rma * (len - 1) + src) / len
rma

_Atr(int length) =>


lentr = math.abs(math.min(length, bar_index))
trueRange = na(high[1])? high-low : math.max(math.max(high - low, math.abs(high
- close[1])), math.abs(low - close[1]))
_RMA(trueRange, lentr)

//-------------------------------
DV(src, vis_atr, vis_std, sed_atr, sed_std) =>
int vis_atrx = math.min(vis_atr, bar_index+1),
int vis_stdx = math.min(vis_std, bar_index+1),
int sed_atrx = math.min(sed_atr, bar_index+1),
int sed_stdx = math.min(sed_std, bar_index+1),
vola = 0.0,
lag_s_K = 0.5,
s1 = nz(vola[1], 0),
s3 = nz(vola[3], 0),
vola := _Atr(vis_atrx) / _Atr(sed_atrx) + lag_s_K * (s1 - s3),
anti_thre = ta.stdev(src, vis_stdx) / ta.stdev(src, sed_stdx),
th = 1.4 - anti_thre,
th := th - vola,

-th * 100

dynamicMedian(float src, int length) =>


if bar_index > length
ta.median(src, length)
else
// Initialize an array of values
var float[] values = array.new_float()

// Fill the array with the last 'length' values, ignoring 'na' values
for i = 0 to length - 1
value = src[i]
if not na(value)
array.push(values, value)

// Only proceed if we have enough data


if array.size(values) > 0
// Sort the array
array.sort(values)

// Calculate the median


size = array.size(values)
float medianValue = na
if size % 2 != 0
// Odd number of elements
medianIndex = (size - 1) / 2
medianValue := array.get(values, medianIndex)
else
// Even number of elements
medianIndex1 = size / 2 - 1
medianIndex2 = size / 2
medianValue := (array.get(values, medianIndex1) + array.get(values,
medianIndex2)) / 2
medianValue
else
na

dispersion(period, TrSens) =>


// Dynamic adjustment of the lookback period based on available data
actualPeriod = math.min (period, bar_index + 1),
linRegLine = ta.linreg(close, actualPeriod, 0),
tes = ta.stdev(close - linRegLine, period)

(tes - dynamicMedian(tes, TrSens)) / 2

dirmov(len) =>
up = ta.change(high)
down = -ta.change(low)
truerange = _RMA(ta.tr, len)
plus = fixnan(100 * _RMA(up > down and up > 0 ? up : 0, len) / truerange)
minus = fixnan(100 * _RMA(down > up and down > 0 ? down : 0, len) /
truerange)
[plus, minus]
Adx(int dilen, int adxlen) =>
up = math.max(ta.change(high), 0)
down = math.max(-ta.change(low), 0)
plusDM = up > down ? up : 0
minusDM = down > up ? down : 0

truerange = math.max(high - low, math.abs(high - close[1]), math.abs(low -


close[1]))
truerange := _RMA(truerange, dilen)

plusDI = 100 * _RMA(plusDM, dilen) / truerange


minusDI = 100 * _RMA(minusDM, dilen) / truerange

sumDI = plusDI + minusDI


adx = 100 * _RMA(math.abs(plusDI - minusDI) / nz(sumDI, 1), adxlen)
adx

int dilen = 14
int adxlen = 14
int adxbase = 20

dvm = DV(close, 10, 30, 20, 100)


sig = (Adx(dilen, adxlen) - adxbase) * 3
dis = dispersion(25, 350)

scale(x, a, b, c, d) =>
c + (d - c)*(x - a) / (b - a)

normalize(currentValue, targetMin, targetMax, window) =>

dynamicLen = math.min(window, 1 + bar_index )


minValue = ta.lowest(currentValue, dynamicLen)
maxValue = ta.highest(currentValue, dynamicLen)
minNew = math.min(currentValue, minValue )
maxNew = math.max(currentValue, maxValue )

output = scale(currentValue, minNew, maxNew, targetMin, targetMax)


minValue != maxValue ? nz(output) : nz(currentValue)

dvm := normalize(dvm, -100, 100, 100)


sig := normalize(sig, -100, 100, 100)
dis := normalize(dis, -100, 100, 100)

mean(_dvm, _sig, _dis) =>


float sum = 0
int count = 0
if not na(dvm)
sum += dvm
count += 1
if not na(sig)
sum += sig
count += 1
if not na(dis)
sum += dis
count += 1
count > 0 ? sum / count : 0

// Calculate the mean


avx = mean(dvm, sig, dis)
avnor = (avx + 100) / 2

avfilter = avnor >= 100? 99 : avnor <=0 ? 1 : avnor


av = avfilter

volatilityText = av < 21? 'ʟᴏᴡ' :


av >= 21 and av < 45 ? 'ᴍᴏᴅᴇʀᴀᴛᴇ':
av >= 45 and av < 70 ? 'ʜɪɢʜ' : 'ᴇxᴛʀᴇᴍᴇ'

backcolor = color.from_gradient(av, 20, 70, color.new(bearZone, 90),


color.new(bearZone, 50))
if trenddashcolor == color.new(bullZone, 50)
backcolor := color.from_gradient(av, 20, 70, color.new(bullZone, 90),
color.new(bullZone, 50))

// trend strength

int dilens = 14
int adxlens = 6
int adxbases = 23

sigxx = (Adx(dilens, adxlens) - adxbases) * 3

sigxx := normalize(sigxx, 0, 100, 100)


sigxx := ta.ema(sigxx, 8)

sigx = sigxx >= 100? 99 : sigxx <= 0 ? 1 : sigxx

strengthcolor = color.from_gradient(sigx, 10, 90, color.new(bearZone, 90),


color.new(bearZone, 50))
if trenddashcolor == color.new(bullZone, 50)
strengthcolor := color.from_gradient(sigx, 10, 90, color.new(bullZone, 90),
color.new(bullZone, 50))

//---------------------------------------------------------------------------------
-------
TABLES-----------------------------------------------------------------------------
bool showT = input.bool(truevar, 'On / Off', group = '======>> Table <<======')

//tamaño----------------------------------------------------
string tamopc = input.string(defval = 'Small',
title = 'Size',
options = ['Tiny', 'Small', 'Normal', 'Large', 'huge'],
inline = 'tables',
group = '======>> Table <<======')

textZise = tamopc == 'Tiny' ? size.tiny :


tamopc == 'Small' ? size.small :
tamopc == 'Normal' ? size.normal :
tamopc == 'Large' ? size.large :
size.huge

// posicion-----------------------------------------------------
string posopc = input.string(defval = 'Bottom-Right',
title = 'Position',
options= ['Bottom-Right', 'Bottom-Center', 'Bottom-Left', 'Top-Left', 'Top-
Center', 'Top-Right'],
group = '======>> Table <<======')

tablePos = posopc == 'Bottom-Right' ? position.bottom_right :


posopc =='Bottom-Center' ? position.bottom_center :
posopc == 'Bottom-Left' ? position.bottom_left :
posopc == 'Top-Left' ? position.top_left :
posopc == 'Top-Center' ? position.top_center :
position.top_right

// inputs
showVola = input.bool(true, 'Volatility', group = '======>> Table <<======')
showStren = input.bool(true, 'Trend Strength', group = '======>> Table <<======')
showTrend = input.bool(true, 'Trend', group = '======>> Table <<======')
showMTF1 = input.bool(true, 'Timeframe 1', inline = 'm1', group = '======>> Table
<<======')
showMTF2 = input.bool(true, 'Timeframe 2', inline = 'm2', group = '======>> Table
<<======')

mtf1 = input.timeframe('30', '', inline = 'm1', group = '======>> Table


<<======')
mtf2 = input.timeframe('1D', '', inline = 'm2', group = '======>> Table
<<======')

// -------------------------------------------------------------------Cálculo del
stop para MTF

convert_timer(tf) =>
pp = tf == '' ? timeframe.period : tf
horax = str.tonumber(pp)
hora = switch
na(horax) => pp
(horax % 60 == 0) => str.tostring(horax/60) + "H"
=> str.tostring(horax) + "m"
hora
var int statemtf = 0
if shortstatus2 == 1 and shortstatus2[1] == 2 and volConfirm
statemtf := 1
if shortstatus2 == 1 and shortstatus2[1] == 2 and noPlus
statemtf := 2
if shortstatus2 == 2 and shortstatus2[1] == 1 and volConfirm
statemtf := 3
if shortstatus2 == 2 and shortstatus2[1] == 1 and noPlus
statemtf := 4

pc4h = request.security(syminfo.tickerid, mtf1, statemtf)


pc1d = request.security(syminfo.tickerid, mtf2, statemtf)

vscolor4h = pc4h == 1 or pc4h == 2 ? color.new(bullZone, 85) : pc4h == 3 or pc4h


== 4 ? color.new(bearZone, 85) : na //color(na)
vscolor1d = pc1d == 1 or pc1d == 2 ? color.new(bullZone, 85) : pc1d == 3 or pc1d
== 4 ? color.new(bearZone, 85) : na //color(na)

vscolor4htxt = pc4h == 1 or pc4h == 2 ? color.new(bullZone, 0) : pc4h == 3 or pc4h


== 4 ? color.new(bearZone, 0) : na //color(na)
vscolor1dtxt = pc1d == 1 or pc1d == 2 ? color.new(bullZone, 0) : pc1d == 3 or pc1d
== 4 ? color.new(bearZone, 0) : na //color(na)

// COLOREADO DE BACKGROUND-----------------------------------------------------

signaltextmtf1 = pc4h == 1 ? '▲✚' :


pc4h == 2 ? '▲' :
pc4h == 3 ? '▼✚' :
pc4h == 4 ? '▼' : na

signaltextmtf2 = pc1d == 1 ? '▲✚' :


pc1d == 2 ? '▲' :
pc1d == 3 ? '▼✚' :
pc1d == 4 ? '▼' : na

ticker = syminfo.ticker
var table myTable = table.new(tablePos, 5, 6, border_width = 1)

if barstate.islast and showT == truevar

table.merge_cells(myTable, start_column = 0, start_row = 0, end_column = 1,


end_row = 0)
table.cell(myTable, 0, 0, text= ticker, bgcolor = color.new(#000000, 100),
text_halign = text.align_center, text_color = color.white, text_size = textZise)
if showTrend
table.cell(myTable, 0, 1, text= 'Trend' , bgcolor = color.new(#FFFFFF, 87),
text_halign = text.align_left, text_color = color.white, text_size = textZise)
table.cell(myTable, 1, 1, text= trenddashtext, bgcolor = trenddashcolor,
text_halign = text.align_left, text_color = color.white, text_size = textZise)

if showStren
table.cell(myTable, 0, 2, text= 'Trend strength' , bgcolor =
color.new(#FFFFFF, 87), text_halign = text.align_left, text_color = color.white,
text_size = textZise)
table.cell(myTable, 1, 2, text= str.tostring(sigx, "#.##") + "%", bgcolor =
strengthcolor, text_halign = text.align_left, text_color = color.white, text_size =
textZise)
if showVola
table.cell(myTable, 0, 3, text= 'Volatility' , bgcolor = color.new(#FFFFFF,
87), text_halign = text.align_left, text_color = color.white, text_size = textZise)
table.cell(myTable, 1, 3, text= volatilityText , bgcolor = backcolor,
text_halign = text.align_left, text_color = color.white, text_size = textZise)
if showMTF1
table.cell(myTable, 0, 4, text= convert_timer(mtf1) , bgcolor =
color.new(#FFFFFF, 87), text_halign = text.align_left, text_color = color.white,
text_size = textZise)
table.cell(myTable, 1, 4, text= signaltextmtf1 , bgcolor = vscolor4h,
text_color = vscolor4htxt, text_size = textZise)
if showMTF2
table.cell(myTable, 0, 5, text= convert_timer(mtf2) , bgcolor =
color.new(#FFFFFF, 87), text_halign = text.align_left, text_color = color.white,
text_size = textZise)
table.cell(myTable, 1, 5, text= signaltextmtf2 , bgcolor = vscolor1d,
text_color = vscolor1dtxt, text_size = textZise)

//---------------------------------------------------------------------------------
------Hyper
Cloud-------------------------------------------------------------------

bool showhyper = input.bool(falsevar, 'On / Off', group = '======>> Hyper Cloud


<<======')
color greencolor = input.color(color.new(#29fff8, 45), 'Bullish', inline = '1',
group = '======>> Hyper Cloud <<======')
color redcolor = input.color(color.new(#ff298d, 45), 'Bearish', inline = '1',
group = '======>> Hyper Cloud <<======')

AP = input( 14, 'Period', group = '======>> Hyper Cloud <<======')


fastval = 1.618
slowval = 3.382
offse = input.int(26, 'offset', minval= 1, group = '======>> Hyper Cloud
<<======')

//------------------------------------------------------------------------------

ATR = ta.atr(AP)
rsi = ta.rsi(close, 21)
rsifast = ta.rsi(close, 6)
//
ti = na(rsi) ? rsifast : rsi
umb = 50

hyper(mult) =>
upH = (math.avg(high, ohlc4)) - ATR * mult
dnH = (math.avg(low, ohlc4)) + ATR * mult

hyperLine = 0.
hyperLine := ti >= umb ? upH < nz(hyperLine[1]) ? nz(hyperLine[1]) : upH : dnH
> nz(hyperLine[1]) ? nz(hyperLine[1]) : dnH
hyperLine

hyperFast = hyper(fastval)
hyperSlow = hyper(slowval)

midtrend = math.avg(hyperFast, hyperSlow)

//Color = hyperFast >= hyperSlow ? greencolor : redcolor


//FColor = hyperFast >= hyperSlow ? greencolor : redcolor

var int hyperstate = 0


if hyperFast>= hyperSlow
hyperstate := 1
if hyperFast<= hyperSlow
hyperstate := 2

//------------------------------------------------

tcolorbull = color.t(greencolor)
tcolorbear = color.t(redcolor)

midtrendColor = hyperstate == 1 ? color.new(greencolor, tcolorbull) :


hyperstate == 2 ? color.new(redcolor, tcolorbear) : na

//---------------------------------------------------------------------------------
---------
// Outputs
//---------------------------------------------------------------------------------
---------
hyper1 = plot(hyperFast > 0.00 and showhyper ? hyperFast : na, "", color=na, offset
= offse-1, display = display.pane, editable = false)
hyper2 = plot(hyperSlow > 0.00 and showhyper ? hyperSlow : na ,"", color=na, offset
= offse-1, display = display.pane, editable = false)
MTMid = plot(hyperSlow > 0.00 and showhyper ? midtrend : na ,"",
color=midtrendColor, offset = offse-1, style = plot.style_line, display =
display.pane, editable = false)

var float intensity = 0.0


var int prev_trend = 0

if hyperstate != prev_trend
intensity := 0.0
prev_trend := hyperstate

intensity := hyperstate == 1 ? math.min(intensity + 1, 45) : hyperstate == 2 ?


math.min(intensity + 1, 45) : intensity
color grad_color = hyperstate == 1 ?
color.from_gradient(intensity, 0, 45, color.new(greencolor, tcolorbull),
color.new(greencolor, tcolorbull + 30)) :
color.from_gradient(intensity, 0, 45, color.new(redcolor, tcolorbear),
color.new(redcolor, tcolorbear + 30))
fill(hyper1, hyper2, grad_color , "", editable = false)

//-------------------------------------------------------------FLEX
TRAILING--------------------------------------------------

bool showmicrotrend = input.bool(truevar, 'On / Off', group = '======>> Dynamic


Trail <<======')

color longColor= input.color(color.new(#29fff8, 30), 'Bullish', inline = 'nube1',


group = '======>> Dynamic Trail <<======')
color shortColor= input.color(color.new(#ff298d, 30), 'Bearish', inline = 'nube1',
group = '======>> Dynamic Trail <<======')

int movingAverageLength = input.int(14, step = 1, minval=1, title="Periods",


inline = 'nube2', group = '======>> Dynamic Trail <<======')
float atrMultiplierMin = input.float(1.482, step = 0.1, minval=0.1,
title="Pressure", inline = 'nube2', group = '======>> Dynamic Trail <<======')
bool showop = input.bool(true, title="Show Opposite Trail?", inline =
'nube3', group = '======>> Dynamic Trail <<======')
color opColor= input.color(#ffffff, '', inline = 'nube3', group = '======>>
Dynamic Trail <<======')
bool showSQ = input.bool(true, title="Show Squeeze?", inline = 'nube4',
group = '======>> Dynamic Trail <<======')
int widthSQ = input.int(2, step = 1, minval=1, title="Width Squeeze", inline
= 'nube5', group = '======>> Dynamic Trail <<======')

tlongdy = color.t(longColor)
tshortdy = color.t(shortColor)

atrlength = 18

medtilson = ta.t3(ohlc4, movingAverageLength, 0.718)

med2 = ta.hma(close, movingAverageLength * 3)


matrail = na(medtilson)? med2 : medtilson //esma(close, movingAverageLength)
rangematrail = ta.atr(atrlength)
//plot(medtilson)

top1 = matrail + rangematrail * atrMultiplierMin


bot1 = matrail - rangematrail * atrMultiplierMin

top1filler = matrail + rangematrail * (atrMultiplierMin- 0.6)


bot1filler = matrail - rangematrail * (atrMultiplierMin- 0.6)

// Dibuja las líneas


var line upper_line = na
var line lower_line = na

colorl = color.white

var line[] upper_lines = array.new_line(20)


var line[] lower_lines = array.new_line(20)
// Función para crear o actualizar líneas
f_create_or_update_line(_lines, _index, _x1, _y1, _x2, _y2, _color) =>
if na(array.get(_lines, _index))
array.set(_lines, _index, line.new(x1=_x1, y1=_y1, x2=_x2, y2=_y2,
color=_color, width=1, style=line.style_dotted))
else
line.set_xy1(array.get(_lines, _index), x=_x1, y=_y1)
line.set_xy2(array.get(_lines, _index), x=_x2, y=_y2)

// Condiciones de cruce
cross_up = ta.crossover(close, top1)
cross_down = ta.crossunder(close, bot1)

var int microstate = 0


fixer = fixnan(microstate[1])
microstate := close > top1 ? 1 : close < bot1 ? 2 : fixer
// Dibujar líneas solo en cruce
if (microstate==1 and showop and showmicrotrend)
for i = 0 to 19
f_create_or_update_line(upper_lines, i, bar_index-i-1, top1[i+1],
bar_index-i, top1[i], _color = opColor)
else if (microstate ==2 and showop and showmicrotrend)
for i = 0 to 19
f_create_or_update_line(lower_lines, i, bar_index-i-1, bot1[i+1],
bar_index-i, bot1[i], _color = opColor)

//-------------------------------------
//---------------------------------------------band AQUEEZE
lenSQ = movingAverageLength //14 //input.int(20, title="Length", minval=1)

aSQ = close - ta.ema(close, lenSQ)


bSQ = aSQ < 0? aSQ * -1: aSQ
dSQ = ta.ema(bSQ, lenSQ)

basisSQ = ta.ema(close, lenSQ)

upperSQ = basisSQ + dSQ


lowerSQ = basisSQ - dSQ

max = math.max(upperSQ, close)


smooth = ta.ema(max, lenSQ)
min = math.min(close, lowerSQ)
smooth2 = ta.ema(min, lenSQ)

rising = ta.rising(smooth2, lenSQ / 5)


falling0 = ta.falling(smooth, lenSQ / 5)
wedge = rising and falling0? smooth: na
wedge2 = rising and falling0? smooth2: na

//fill trail
filltop1 = ta.wma(top1filler, 3)
fillbot1 = ta.wma(bot1filler, 3)

dif = (filltop1 - fillbot1)


lastcond = dif<dif[1]

//
var float fillstate = 0
fixerfill= fixnan(fillstate[1])
fillstate := microstate ==1 ? 1 : microstate == 2 ? 2 : fixerfill

//-----------------------------------
SWITCH-----------------------------------------------------------------------------

micro1 = microstate == 2 ? top1 : microstate ==1? bot1 : na


plotmicro1 = plot(showmicrotrend ? micro1 : na, color = microstate == 2 ?
shortColor : microstate == 1 ? longColor : na,
editable = falsevar,
display = display.pane)

micro2 = fillstate == 2 ? filltop1 : fillstate ==1? fillbot1 : na


plotmicro2 = plot(showmicrotrend ? micro2 : na, color = na,
editable = falsevar,
display = display.pane)

// SQUEEZE PLOTS
var int sqstate = 0
if (rising and falling0) and lastcond and showmicrotrend and showSQ and microstate
== 1
sqstate := 1
if (rising and falling0) and lastcond and showmicrotrend and showSQ and microstate
== 2
sqstate := 2

sqcond = (rising and falling0) and lastcond and showmicrotrend and showSQ and
microstate == 1 ? bot1 :
(rising and falling0) and lastcond and showmicrotrend and showSQ and
microstate == 2 ? top1 : na

plot(sqcond,
style = plot.style_cross, linewidth = widthSQ,
color = microstate == 2 ? color.new(shortColor, tlongdy) : microstate == 1 ?
color.new(longColor, tshortdy) : na,
editable = falsevar,
display = display.pane)

var int sqStateDy = 0

if (rising and falling0) and lastcond


sqStateDy:= 1
if not((rising and falling0) and lastcond)
sqStateDy:= 2

//fills
fillcolorMicrotrend = microstate == 2 ? color.new(shortColor, 70) :
microstate == 1 ? color.new(longColor, 70) : na

var float intensitydy = 0.0


var int prev_trenddy = 0

if microstate != prev_trenddy
intensitydy := 0.0
prev_trenddy := microstate

intensitydy := microstate == 1 ? math.min(intensitydy + 1, 45) : microstate == 2 ?


math.min(intensitydy + 1, 45) : intensitydy
color grad_colordy = microstate == 1 ?
color.from_gradient(intensitydy, 0, 45, color.new(longColor, tlongdy + 10),
color.new(longColor, tlongdy + 50)) :
color.from_gradient(intensitydy, 0, 45, color.new(shortColor, tshortdy + 10),
color.new(shortColor, tshortdy + 50))

fill(plot1 = plotmicro1, plot2 = plotmicro2, color = grad_colordy, editable =


falsevar)

//--------------------------------------------------------------MARKET
BIAS-------------------------------------

bool showchbias = input.bool(falsevar, 'On / Off', group="======>> Market Bias


<<======")
color Colorbullvc= input.color(color.new(#29fff8, 20), 'Bull', inline = 'vc1',
group="======>> Market Bias <<======")
color Colorbearvc= input.color(color.new(#ff298d, 20), 'Bear', inline = 'vc1',
group="======>> Market Bias <<======")
int periodsvc = input.int(50, 'Periods', minval = 1, group="======>> Market Bias
<<======")
float multoutvc = input.float(2, 'Amplitude', minval = 0.1, inline = 'vc2', step=
0.1, group="======>> Market Bias <<======")
float multinvc = multoutvc - 0.6 //input.float(1.4, 'Inner Amplitude', minval =
0.1, inline = 'vc3', step= 0.1, group="======>> Market Bias <<======")
bool showbiasch = input.bool(true, 'Show Channel', group="======>> Market Bias
<<======")

//----------------------------------------------------------------

//the same on pine


myatr(bia,length) =>
trueRange = na(high[1])? high-low : math.max(math.max(high - low, math.abs(high
- bia[1])), math.abs(low - bia[1]))
//true range can be also calculated with ta.tr(true)
ta.rma(trueRange, length)
biasupvc = ta.ema(high, periodsvc)
biasdnvc = ta.ema(low, periodsvc)
atr1 = myatr(biasupvc, 100)
atr2 = myatr(biasdnvc, 100)

// Definición de la función para calcular RSI y Trailing Stop


f_trailing_stop(indicator, factor) =>
var float ts = na

delta = indicator - indicator[1]


w = nz(delta * (indicator - ts) > 0 ? 2 : 1, 1)

// Calcular la media móvil de las diferencias absolutas


diff = ta.rma(math.abs(indicator - indicator[1]), 14)
crossover = ta.crossover(indicator, ts)
crossunder = ta.crossunder(indicator, ts)

ts := nz(crossover ? indicator - diff * factor


: crossunder ? indicator + diff * factor
: indicator > ts ? math.max(indicator - diff * factor, ts)
: math.min(indicator + diff * factor, ts), indicator)

ts

//-----calculos

// outer channels calculos


dev1vc = multoutvc * atr1
upperoutvc = biasupvc + dev1vc

dev2vc = multoutvc * atr2


loweroutvc = biasdnvc - dev2vc

biasvc = math.avg(upperoutvc, loweroutvc)

signalvc = f_trailing_stop(biasvc, 2.238)

atr3 = myatr(biasupvc, 60)


atr4 = myatr(biasdnvc, 60)

// inner channels calculos


dev3vc = multinvc * atr3
_upperinvc = biasupvc + dev3vc
upperinvc = ta.wma(_upperinvc, 3)

dev4vc = multinvc * atr4


_lowerinvc = biasdnvc - dev4vc
lowerinvc = ta.wma(_lowerinvc, 3)
tcolorbullM = color.t(Colorbullvc)
tcolorbearM = color.t(Colorbearvc)

//bullBias = getGradientColor(close, maxValM, minValM, shortColorStartM,


shortColorEndM)
bullBias = color.from_gradient(ta.ema(close, 6), loweroutvc, upperoutvc,
color.new(Colorbearvc, tcolorbearM + 75), color.new(Colorbearvc, tcolorbearM + 30))
bearBias = color.from_gradient(ta.ema(close, 6), loweroutvc, upperoutvc,
color.new(Colorbullvc, tcolorbullM + 30), color.new(Colorbullvc, tcolorbullM + 75))

//----plot bias
plotbias = plot(showchbias ? biasvc : na, color = biasvc< signalvc?
color.new(Colorbearvc, tcolorbearM + 20) : biasvc> signalvc? color.new(Colorbullvc,
tcolorbullM + 20): color.new(color.white, 50), editable = falsevar, display =
display.pane)
plotsignal =plot(showchbias ? signalvc : na, color = biasvc< signalvc?
color.new(Colorbearvc, tcolorbearM + 20): biasvc> signalvc? color.new(Colorbullvc,
tcolorbullM + 20) : color.new(color.white, 50), editable = falsevar, display =
display.pane)

//----- plot outer


plotuppervc = plot(showbiasch? upperoutvc : na, color = color.new(bullBias,
tcolorbearM + 90), editable = falsevar, display = display.pane)
plotlowervc = plot(showbiasch? loweroutvc : na, color = color.new(bearBias,
tcolorbullM + 90), editable = falsevar, display = display.pane)
//----plot inner
plotupperinvc = plot(showbiasch? upperinvc : na, color = na, editable = falsevar,
display = display.pane)
plotlowerinvc =plot(showbiasch? lowerinvc : na, color = na, editable = falsevar,
display = display.pane)

fill(plotuppervc, plotupperinvc, color = bullBias, editable = falsevar)


fill(plotlowervc, plotlowerinvc, color = bearBias, editable = falsevar)

fill(plotbias, plotsignal, color = biasvc< signalvc? color.new(Colorbearvc,


tcolorbearM + 20) : color.new(Colorbullvc, tcolorbullM + 20))

// ----------------------------------------------------TREND DRIVER
showtd = input.bool(falsevar, title = 'On / Off', group="======>> Trend Driver
<<======")
periodTD = input.int(3, minval = 1, title = 'Period', group="======>> Trend Driver
<<======" )
bullcolorTD = input.color(#29fff8, inline = 'colortd', title = 'Bullish',
group="======>> Trend Driver <<======" )
bearcolorTD = input.color(#ff298d, inline = 'colortd', title = 'Bearish',
group="======>> Trend Driver <<======" )
thicknessTD = input.int(2, 'thickness', minval = 1, group="======>> Trend Driver
<<======" )
coloreoTD = input.string('Original', title = 'Coloring', options = ['Original',
'Refined'])
tdoriginal = tdFunction(periodTD)

var float track = 0.


track := tdoriginal > tdoriginal[1] ? 1 : tdoriginal < tdoriginal[1] ? 2 :
nz(track[1])

//------------ refined

periodTDref = periodTD - 1
periodTDref := periodTDref == 0 ? 1 : periodTDref

tdrefinado = tdFunction(periodTDref)

//plot(tdR)
var int refinstate = 0
refinstate := tdrefinado> tdoriginal ? 1 : tdrefinado < tdoriginal? 2 :
nz(refinstate)

colortrendDriver = track == 1 and coloreoTD == 'Original' ? color.new(bullcolorTD,


0) :
track == 2 and coloreoTD == 'Original' ? color.new(bearcolorTD, 0)
:
refinstate == 1 and coloreoTD == 'Refined' ?
color.new(bullcolorTD, 0) :
refinstate == 2 and coloreoTD == 'Refined' ?
color.new(bearcolorTD, 0) : na
cololast = periodTDref == 1 and track == 1 and (coloreoTD == 'Original' or
coloreoTD == 'Refined') ? color.new(bullcolorTD, 0) :
periodTDref == 1 and track == 2 and (coloreoTD == 'Original' or
coloreoTD == 'Refined') ? color.new(bearcolorTD, 0) : colortrendDriver

don1 = plot(showtd ? tdoriginal : na, color = cololast, linewidth = thicknessTD,


editable = falsevar, display = display.pane)

//---------------------------------------------------------------------------------
----------------
TOOLS------------------------------------------------------------------------------
--------------------

string tools = input.string('None', 'Tool', options = ['Bollinger Bands', 'Ribbon',


'Donchian Channels', 'None'], group="======>> Tools <<======")
string lookbasis = input.string('None', title = 'Show basis?', options = ['Bands',
'Channel', 'None'], group="======>> Tools <<======")
int thickness = input.int(1, minval = 1, title = 'Thickness', group="======>>
Tools <<======", tooltip = 'Baseline thickness')

color Color2= input.color(color.new(#29fff8, 0), 'Bull', inline = 'Tools1',


group="======>> Tools <<======")
color Color1= input.color(color.new(#ff298d, 0), 'Bear', inline = 'Tools1',
group="======>> Tools <<======")

periodoshb = input.int(20, 'Periods', minval = 1, group="======>> Tools


<<======")
multhb = input.float(4, 'Deviation', minval = 0.1, step= 0.1, group="======>>
Tools <<======", tooltip = 'Deviation of Bollinger bands')
increhb = input.int(20, 'Increase', minval = 3, step= 10, group="======>> Tools
<<======", tooltip = 'Rising ribbon moving averages')

// -------------------------------------------
RIBBON-----------------------------------

dema(close, length) =>


e1 = ta.ema(close, length)
e2 = ta.ema(e1, length)
dema = 2 * e1 - e2
dema

st = dema(close, periodoshb)
st1 = dema(close, periodoshb + increhb)
st2 = dema(close, periodoshb + 2* increhb)
st3 = dema(close, periodoshb + 3* increhb)
st4 = dema(close, periodoshb + 4* increhb)
st5 = dema(close, periodoshb + 5* increhb)
//---------------------------------------------------------------------------------
--VOLATITLY BANDS---------------------------------------------------------------

upperval1 = ta.sma(high, periodoshb )


//upperval2 = math.avg(ta.ema(high, periodoshb), upperval1)

dev1 = multhb * ta.dev(upperval1, periodoshb )


upper = upperval1 + dev1

dev3 = (multhb / 4)* ta.dev(high, periodoshb )


upperup1 = upper + dev3

dev5 = (multhb / 4)* ta.dev(high, periodoshb) //) ta.atr(periodoshb )


upperup2 = upperup1 + dev5

lowerval1 = ta.sma(low, periodoshb )


//lowerval2 = math.avg(ta.ema(low, periodoshb), lowerval1)
dev2 = multhb * ta.dev(lowerval1, periodoshb )
lower = lowerval1 - dev2

dev4 = (multhb / 4)* ta.dev(low, periodoshb )


lowerlow1 = lower - dev4

dev6 = (multhb / 4)* ta.dev(low, periodoshb) //) ta.atr(periodoshb )


lowerlow2 = lowerlow1 - dev6

//--------------BASIS

stema = math.avg(upper,lower)
sm = ta.ema(stema, 3)
tsr = 0.47
tsrp = tsr*100

spread = upper - lower


maxspread = ta.sma(spread,100)

bbs = (spread/maxspread)*100

var int sqstatevol = 0

if bbs>tsrp
sqstatevol := 1
if not(bbs>tsrp)
sqstatevol := 2

//---------------------------------------------------------------------------------
------------------------DONCHIAN
cHANNELS---------------------------------------------------------------------------
--------------

int dc_lkbk = periodoshb

upperdc = ta.highest( dc_lkbk)


lowerdc = ta.lowest( dc_lkbk)

inner_upper0 = ta.highest(fuenteclose, dc_lkbk)


//inner_upper = ta.ema(inner_upper0, 1)
inner_lower0 = ta.lowest(fuenteclose, dc_lkbk)
//inner_lower = ta.ema(inner_lower0, 1)

basis = math.avg(upperdc, lowerdc)

emabase = ta.ema(basis, 9)

//---------------------------------------------------------------------------------
---------SWITCH DE LINE
BASE-------------------------------------------------------------------------------
---------------------

colorBase = lookbasis=='Bands' and stema>= sm ? color.new(Color2, 60) :


lookbasis == 'Bands' and stema< sm ? color.new(Color1, 60) :
lookbasis == 'Channel' and basis >= emabase ? color.new(Color2, 30) :
lookbasis == 'Channel' and basis < emabase ? color.new(Color1, 30) :
na

float base = switch lookbasis


'Bands' => stema
'Channel' => basis
plotb = plot(base, editable = falsevar, color= colorBase,
display = display.pane,
style = plot.style_line, linewidth = thickness)

coloremacd = stema>= sm? color.new(Color2, 60) :


stema< sm? color.new(Color1, 60) : na

plotmacd = plot( lookbasis=='Bands'? sm : na, color = coloremacd, editable =


falsevar, display = display.pane )

coloremacdfill = lookbasis == 'Bands' and stema>= sm? color.new(Color2, 50) :


lookbasis == 'Bands' and stema< sm? color.new(Color1, 50) : na

fill(plotb, plotmacd, color = coloremacdfill)


//---------------------------------------------------------------------------------
---------
SWITCH-----------------------------------------------------------------------------
------------------------------------

float s = switch tools


'Bollinger Bands' => upperup2 //ta.ema(ta.ema(medianAvg, av) + devHigh, 9)
'Ribbon' => st
'Donchian Channels'=> upperdc

ta = plot(s, editable = falsevar, color =tools=='Bollinger Bands' and bbs< tsrp ?


Color1 :na, style = plot.style_cross, display = display.pane, linewidth = 1)
float s1 = switch tools
'Bollinger Bands' => lowerlow2 //ta.ema(ta.ema(medianAvg, av) - devLow, 9)
'Ribbon' => st1
'Donchian Channels'=> lowerdc

t1 = plot(s1, editable = falsevar, color =tools=='Bollinger Bands' and bbs< tsrp ?


Color2 :na, style = plot.style_cross, display = display.pane, linewidth = 1)
float s2 = switch tools
'Bollinger Bands' => upperup1
'Ribbon' => st2
'Donchian Channels'=> inner_upper0

t2 = plot(s2, editable = falsevar, color = na, display = display.pane)


float s3 = switch tools
'Bollinger Bands' => lowerlow1
'Ribbon' => st3
'Donchian Channels'=> inner_lower0

t3 = plot(s3, editable = falsevar, color = na, display = display.pane)


float s4 = switch tools
'Bollinger Bands' => upper
'Ribbon' => st4
//'Donchian Channels'=>

t4 = plot(s4, editable = falsevar, color = na, display = display.pane)


float s5 = switch tools
'Bollinger Bands' => lower
'Ribbon' => st5
//'Donchian Channels'=>

t5 = plot(s5, editable = falsevar, color = na, display = display.pane)

//-------------------------fill de bandas y donchian


--------------------------------------------------------
fill( ta, t2 , color = tools == 'Bollinger Bands' ? color.new(Color1, 60) :
tools == 'Donchian Channels' ? color.new(Color1, 60) : na)

fill( t2, t4 , color = tools == 'Bollinger Bands' ? color.new(Color1, 81) : na)

fill(t1, t3 , color = tools == 'Bollinger Bands' ? color.new(Color2, 60) :


tools == 'Donchian Channels' ? color.new(Color2, 60) : na)

fill(t3, t5 , color = tools == 'Bollinger Bands' ? color.new(Color2, 81) : na)

//****************************fill
ribbon---------------------------------------------------------
fill(ta, t1, color = tools == 'Ribbon' and st > st1 ? color.new(Color2, 93) :
tools == 'Ribbon' and st < st1 ? color.new(Color1, 93) : na)
fill(t1, t2, color = tools == 'Ribbon' and st1 > st2 ? color.new(Color2, 78) :
tools == 'Ribbon' and s1 < st2 ? color.new(Color1, 78) : na)
fill(t2, t3, color = tools == 'Ribbon' and st2 > st3 ? color.new(Color2, 65) :
tools == 'Ribbon' and s2 < st3 ? color.new(Color1, 65) : na)
fill(t3, t4, color = tools == 'Ribbon' and st3 > st4 ? color.new(Color2, 52) :
tools == 'Ribbon' and s3 < st4 ? color.new(Color1, 52) : na)
fill(t4, t5, color = tools == 'Ribbon' and st4 > st5 ? color.new(Color2, 39) :
tools == 'Ribbon' and s4 < st5 ? color.new(Color1, 39) : na)

//////-----------------------------------------------
//-----------------------------------------------------------------------------{
//Boolean set
//-----------------------------------------------------------------------------{
s_BOS = 0
s_CHoCH = 1
i_BOS = 2
i_CHoCH = 3
i_pp_CHoCH = 4
green_candle = 5
red_candle = 6
s_CHoCHP = 7
i_CHoCHP = 8

boolean =
array.from(
false
, false
, false
, false
, false
, false
, false
, false
, false
)

//-----------------------------------------------------------------------------{
// User inputs
//-----------------------------------------------------------------------------{

show_swing_ms = input.string ("All", "Swing", inline = "1",


group ="======>> MARKET STRUCTURE <<======", options = ["All", "CHoCH", "CHoCH+",
"BOS", "None"])
show_internal_ms = input.string ("All", "Internal", inline =
"2", group = "======>> MARKET STRUCTURE <<======", options = ["All", "CHoCH",
"CHoCH+", "BOS", "None"])
internal_r_lookback = input.int (5, "", inline = "2", group =
"======>> MARKET STRUCTURE <<======", minval = 2)
swing_r_lookback = input.int (30, "", inline = "1", group =
"======>> MARKET STRUCTURE <<======", minval = 2)
ms_mode = 'Manual'

i_ms_up_BOS = input.color (#29fff8, "", inline = "2", group


= "======>> MARKET STRUCTURE <<======")
i_ms_dn_BOS = input.color (#ff298d, "", inline = "2", group
= "======>> MARKET STRUCTURE <<======")
s_ms_up_BOS = input.color (#29fff8, "", inline = "1", group
= "======>> MARKET STRUCTURE <<======")
s_ms_dn_BOS = input.color (#ff298d, "", inline = "1", group
= "======>> MARKET STRUCTURE <<======")

ob_show = input.bool (true, "On / Off", inline =


"1a", group = "======>> VOLUMETRIC ORDER BLOCK <<======" )
ob_bull_css = input.color (color.new(#29fff8, 90), "",
inline = "1", group = "======>> VOLUMETRIC ORDER BLOCK <<======")
ob_bear_css = input.color (color.new(#ff298d, 90), "",
inline = "1", group = "======>> VOLUMETRIC ORDER BLOCK <<======")

ob_num = input.int (2, "Show last", inline = "1b",


group = "======>> VOLUMETRIC ORDER BLOCK <<======", tooltip = "Orderblocks number
1 - 10", minval = 1, maxval = 10)
ob_metrics_show = true

ob_filter = 'None'
ob_mitigation = 'Absolute'
ob_pos = 'Precise'
use_grayscale = false
use_show_metric = true
use_middle_line = true
use_overlap = true
use_overlap_method = 'Previous'

t = color.t(ob_bull_css)
invcol = color.new(color.white, 100)

//{ - UDT

type bar
float o = open
float c = close
float h = high
float l = low
float v = volume
int n = bar_index
int t = time

type ms
float[] p
int [] n
float[] l

type msDraw
int n
float p
color css
string txt
bool bull

type obC
float[] top
float[] btm
int [] left
float[] avg
float[] dV
float[] cV
int [] wM
int [] blVP
int [] brVP
int [] dir
float[] h
float[] l
int [] n

type obD
box [] ob
box [] eOB
box [] blB
box [] brB
line[] mL

type alerts
bool chochswing = false
bool chochplusswing = false
bool swingbos = false
bool chochplus = false
bool choch = false
bool bos = false
bool ob = false
bool swingob = false
bool obtouch = false

// General Setup

bar b = bar.new()

alerts blalert = alerts.new()


alerts bralert = alerts.new()

switch
b.c > b.o => boolean.set(green_candle, true)
b.c < b.o => boolean.set(red_candle , true)

f_zscore(src, lookback) =>

(src - ta.sma(src, lookback)) / ta.stdev(src, lookback)

var int iLen = internal_r_lookback


var int sLen = swing_r_lookback

vv = f_zscore(((close - close[iLen]) / close[iLen]) * 100,iLen)

var msline = array.new<line>(0)

iH = ta.pivothigh(high, iLen, iLen)


sH = ta.pivothigh(high, sLen, sLen)
iL = ta.pivotlow (low , iLen, iLen)
sL = ta.pivotlow (low , sLen, sLen)

//Market Structure

method darkcss(color css, float factor, bool bull) =>

blue = color.b(css) * (1 - factor)


red = color.r(css) * (1 - factor)
green = color.g(css) * (1 - factor)

color.rgb(red, green, blue, 0)

method f_line(msDraw d, size, style) =>

var line id = na
var label lbl = na

id := line.new(
d.n
, d.p
, b.n
, d.p
, color = d.css
, width = 1
, style = style
)

if msline.size() >= 250

line.delete(msline.shift())

msline.push(id)

lbl := label.new(
int(math.avg(d.n, b.n))
, d.p
, d.txt
, color = invcol
, textcolor = d.css
, style = d.bull ? label.style_label_down : label.style_label_up
, size = size
)

structure(bool mtf) =>

msDraw drw = na

bool isdrw = false


bool isdrwS = false

var color css = na


var color icss = na

var int itrend = 0


var int trend = 0

bool bull_ob = false


bool bear_ob = false

bool s_bull_ob = false


bool s_bear_ob = false

n = bar_index

var ms up = ms.new(
array.new<float>()
, array.new< int >()
, array.new<float>()
)

var ms dn = ms.new(
array.new<float>()
, array.new< int >()
, array.new<float>()
)

var ms sup = ms.new(


array.new<float>()
, array.new< int >()
, array.new<float>()
)

var ms sdn = ms.new(


array.new<float>()
, array.new< int >()
, array.new<float>()
)

switch show_swing_ms

"All" => boolean.set(s_BOS , true ), boolean.set(s_CHoCH, true ) ,


boolean.set(s_CHoCHP, true )
"CHoCH" => boolean.set(s_BOS , false), boolean.set(s_CHoCH, true ) ,
boolean.set(s_CHoCHP, false )
"CHoCH+" => boolean.set(s_BOS , false), boolean.set(s_CHoCH, false) ,
boolean.set(s_CHoCHP, true )
"BOS" => boolean.set(s_BOS , true ), boolean.set(s_CHoCH, false) ,
boolean.set(s_CHoCHP, false )
"None" => boolean.set(s_BOS , false), boolean.set(s_CHoCH, false) ,
boolean.set(s_CHoCHP, false )
=> na

switch show_internal_ms

"All" => boolean.set(i_BOS, true ), boolean.set(i_CHoCH, true ),


boolean.set(i_CHoCHP, true )
"CHoCH" => boolean.set(i_BOS, false), boolean.set(i_CHoCH, true ),
boolean.set(i_CHoCHP, false)
"CHoCH+" => boolean.set(i_BOS, false), boolean.set(i_CHoCH, false ),
boolean.set(i_CHoCHP, true )
"BOS" => boolean.set(i_BOS, true ), boolean.set(i_CHoCH, false ),
boolean.set(i_CHoCHP, false)
"None" => boolean.set(i_BOS, false), boolean.set(i_CHoCH, false ),
boolean.set(i_CHoCHP, false)
=> na

switch
not na(iH) =>

up.p.unshift((b[iLen]).h)
up.l.unshift((b[iLen]).h)
up.n.unshift(n [iLen])

not na(iL) =>

dn.p.unshift((b[iLen]).l)
dn.l.unshift((b[iLen]).l)
dn.n.unshift(n [iLen])

not na(sL) =>

sdn.p.unshift((b[sLen]).l)
sdn.l.unshift((b[sLen]).l)
sdn.n.unshift(n [sLen])

not na(sH) =>

sup.p.unshift((b[sLen]).h)
sup.l.unshift((b[sLen]).h)
sup.n.unshift(n [sLen])

// INTERNAL BULLISH STRUCTURE


if up.p.size() > 0 and dn.l.size() > 1

if ta.crossover(b.c, up.p.first())

bool CHoCH = false


string txt = na

if itrend < 0

CHoCH := true

switch

not CHoCH =>


txt := "BOS"
css := i_ms_up_BOS

blalert.bos := true

if boolean.get(i_BOS) and mtf == false and na(drw)

isdrw := true
drw := msDraw.new(
up.n.first()
, up.p.first()
, i_ms_up_BOS
, txt
, true
)

CHoCH =>

if dn.l.first() > dn.l.get(1)


blalert.chochplus := true
else
blalert.choch := true

txt := dn.l.first() > dn.l.get(1) ? "CHoCH+" :


"CHoCH"
css := i_ms_up_BOS

if (dn.l.first() > dn.l.get(1) ?


boolean.get(i_CHoCHP) : boolean.get(i_CHoCH)) and mtf == false and na(drw)

isdrw := true
drw := msDraw.new(
up.n.first()
, up.p.first()
, i_ms_up_BOS
, txt
, true
)

if mtf == false

switch

ob_filter == "None" =>


bull_ob := true
ob_filter == "BOS" and txt == "BOS" =>
bull_ob := true
ob_filter == "CHoCH" and txt == "CHoCH" =>
bull_ob := true
ob_filter == "CHoCH+" and txt == "CHoCH+" =>
bull_ob := true

itrend := 1
up.n.clear()
up.p.clear()

// INTERNAL BEARISH STRUCTURE


if dn.p.size() > 0 and up.l.size() > 1
if ta.crossunder(b.c, dn.p.first())

bool CHoCH = false


string txt = na

if itrend > 0

CHoCH := true

switch

not CHoCH =>

bralert.bos := true

txt := "BOS"
css := i_ms_dn_BOS

if boolean.get(i_BOS) and mtf == false and na(drw)

isdrw := true
drw := msDraw.new(
dn.n.first()
, dn.p.first()
, i_ms_dn_BOS
, txt
, false
)

CHoCH =>

if up.l.first() < up.l.get(1)


bralert.chochplus := true
else
bralert.choch := true

txt := up.l.first() < up.l.get(1) ? "CHoCH+" :


"CHoCH"
css := i_ms_dn_BOS

if (up.l.first() < up.l.get(1) ?


boolean.get(i_CHoCHP) : boolean.get(i_CHoCH)) and mtf == false and na(drw)

isdrw := true
drw := msDraw.new(
dn.n.first()
, dn.p.first()
, i_ms_dn_BOS
, txt
, false
)

if mtf == false

switch

ob_filter == "None" =>


bear_ob := true
ob_filter == "BOS" and txt == "BOS" =>
bear_ob := true
ob_filter == "CHoCH" and txt == "CHoCH" =>
bear_ob := true
ob_filter == "CHoCH+" and txt == "CHoCH+" =>
bear_ob := true

itrend := -1
dn.n.clear()
dn.p.clear()

// SWING BULLISH STRUCTURE


if sup.p.size() > 0 and sdn.l.size() > 1

if ta.crossover(b.c, sup.p.first())

bool CHoCH = false


string txt = na

if trend < 0

CHoCH := true

switch

not CHoCH =>

blalert.swingbos := true

txt := "BOS"
icss := s_ms_up_BOS

if boolean.get(s_BOS) and mtf == false and na(drw)

isdrwS := true
drw := msDraw.new(
sup.n.first()
, sup.p.first()
, s_ms_up_BOS
, txt
, true
)

CHoCH =>

if sdn.l.first() > sdn.l.get(1)


blalert.chochplusswing := true
else
blalert.chochswing := true

txt := sdn.l.first() > sdn.l.get(1) ? "CHoCH+" :


"CHoCH"
icss := s_ms_up_BOS

if (sdn.l.first() > sdn.l.get(1) ?


boolean.get(s_CHoCHP) : boolean.get(s_CHoCH)) and mtf == false and na(drw)

isdrwS := true
drw := msDraw.new(
sup.n.first()
, sup.p.first()
, s_ms_up_BOS
, txt
, true
)

if mtf == false

switch

ob_filter == "None" =>


s_bull_ob := true
ob_filter == "BOS" and txt == "BOS" =>
s_bull_ob := true
ob_filter == "CHoCH" and txt == "CHoCH" =>
s_bull_ob := true
ob_filter == "CHoCH+" and txt == "CHoCH+" =>
s_bull_ob := true

trend := 1
sup.n.clear()
sup.p.clear()

// SWING BEARISH STRUCTURE


if sdn.p.size() > 0 and sup.l.size() > 1

if ta.crossunder(b.c, sdn.p.first())

bool CHoCH = false


string txt = na

if trend > 0

CHoCH := true

switch

not CHoCH =>

bralert.swingbos := true

txt := "BOS"
icss := s_ms_dn_BOS

if boolean.get(s_BOS) and mtf == false and na(drw)

isdrwS := true
drw := msDraw.new(
sdn.n.first()
, sdn.p.first()
, s_ms_dn_BOS
, txt
, false
)

CHoCH =>

if sup.l.first() < sup.l.get(1)


bralert.chochplusswing := true
else
bralert.chochswing := true

txt := sup.l.first() < sup.l.get(1) ? "CHoCH+" :


"CHoCH"
icss := s_ms_dn_BOS

if (sup.l.first() < sup.l.get(1) ?


boolean.get(s_CHoCHP) : boolean.get(s_CHoCH)) and mtf == false and na(drw)

isdrwS := true
drw := msDraw.new(
sdn.n.first()
, sdn.p.first()
, s_ms_dn_BOS
, txt
, false
)

if mtf == false

switch

ob_filter == "None" =>


s_bear_ob := true
ob_filter == "BOS" and txt == "BOS" =>
s_bear_ob := true
ob_filter == "CHoCH" and txt == "CHoCH" =>
s_bear_ob := true
ob_filter == "CHoCH+" and txt == "CHoCH+" =>
s_bear_ob := true

trend := -1
sdn.n.clear()
sdn.p.clear()

[css, bear_ob, bull_ob, itrend, drw, isdrw, s_bear_ob, s_bull_ob, trend, icss,
isdrwS]

[css, bear_ob, bull_ob, itrend, drw, isdrw, s_bear_ob, s_bull_ob, trend, icss,
isdrwS] = structure(false)

if isdrw
f_line(drw, size.small, line.style_dashed)

if isdrwS
f_line(drw, size.small, line.style_solid)

//Volumetric Order Block

method eB(box[] b, bool ext, color css, bool swing) =>


b.unshift(
box.new(
na
, na
, na
, na
, xloc = xloc.bar_time
, extend = ext ? extend.right : extend.none
, border_color = swing ? color.new(css, 0) :
color.new(color.white,100)
, bgcolor = css
, border_width = 1
)
)

method eL(line[] l, bool ext, bool solid, color css) =>


l.unshift(
line.new(
na
, na
, na
, na
, width = 1
, color = css
, xloc = xloc.bar_time
, extend = ext ? extend.right : extend.none
, style = solid ? line.style_solid : line.style_dashed
)
)

method drawVOB(bool cdn, bool bull, color css, int loc, bool swing) =>

[cC, oO, hH, lL, vV] = request.security(


syminfo.tickerid
, ""

, [

close
, open
, high
, low
, volume

, lookahead = barmerge.lookahead_off
)
var obC obj = obC.new(
array.new<float>()
, array.new<float>()
, array.new< int >()
, array.new<float>()
, array.new<float>()
, array.new<float>()
, array.new< int >()
, array.new< int >()
, array.new< int >()
, array.new< int >()
, array.new<float>()
, array.new<float>()
, array.new< int >()
)

var obD draw = obD.new(


array.new<box >()
, array.new<box >()
, array.new<box >()
, array.new<box >()
, array.new<line>()
)

if barstate.isfirst

for i = 0 to ob_num - 1

draw.mL .eL(false, false, use_grayscale ? color.new(color.gray, 0) :


color.new(css,0))
draw.ob .eB(false, use_grayscale ? color.new(color.gray, 90) : css,
swing)
draw.blB.eB(false, color.new(ob_bull_css, 60)
, swing)
draw.brB.eB(false, color.new(ob_bear_css, 60)
, swing)
draw.eOB.eB(true , use_grayscale ? color.new(color.gray, 90) : css,
swing)

float pos = ob_pos == "Full"


? (bull ? high : low)
: ob_pos == "Middle"
? ohlc4
: ob_pos == "Accurate"
? hl2
: hl2

if cdn

obj.h.clear()
obj.l.clear()
obj.n.clear()

for i = 1 to math.abs((loc - b.n)) - 1

obj.h.push(hH[i])
obj.l.push(lL[i])
obj.n.push(b.t[i])

int iU = obj.l.indexof(obj.l.min()) + 1
int iD = obj.h.indexof(obj.h.max()) + 1

obj.dir.unshift(
bull
? (b.c[iU] > b.o[iU] ? 1 : -1)
: (b.c[iD] > b.o[iD] ? 1 : -1)
)
obj.top.unshift(
bull
? pos[iU]
: obj.h.max()
)

obj.btm.unshift(
bull
? obj.l.min()
: pos[iD]
)

obj.left.unshift(
bull
? obj.n.get(obj.l.indexof(obj.l.min()))
: obj.n.get(obj.h.indexof(obj.h.max()))
)

obj.avg.unshift(
math.avg(obj.top.first(), obj.btm.first())
)

obj.cV.unshift(
bull
? b.v[iU]
: b.v[iD]
)

if ob_pos == "Precise"

switch bull
true =>
if obj.avg.get(0) < (b.c[iU] < b.o[iU] ? b.c[iU] : b.o[iU]) and
obj.top.get(0) > hlc3[iU]
obj.top.set(0, obj.avg.get(0))
obj.avg.set(0, math.avg(obj.top.first(), obj.btm.first()))
false =>
if obj.avg.get(0) > (b.c[iU] < b.o[iU] ? b.o[iD] : b.c[iD]) and
obj.btm.get(0) < hlc3[iD]
obj.btm.set(0, obj.avg.get(0))
obj.avg.set(0, math.avg(obj.top.first(), obj.btm.first()))

obj.blVP.unshift ( 0 )
obj.brVP.unshift ( 0 )
obj.wM .unshift ( 1 )

if use_overlap

int rmP = use_overlap_method == "Recent" ? 1 : 0

if obj.avg.size() > 1

if bull

? obj.btm.first() < obj.top.get(1)


: obj.top.first() > obj.btm.get(1)
obj.wM .remove(rmP)
obj.cV .remove(rmP)
obj.dir .remove(rmP)
obj.top .remove(rmP)
obj.avg .remove(rmP)
obj.btm .remove(rmP)
obj.left .remove(rmP)
obj.blVP .remove(rmP)
obj.brVP .remove(rmP)

if barstate.isconfirmed

for x = 0 to ob_num - 1

tg = switch ob_mitigation
"Middle" => obj.avg
"Absolute" => bull ? obj.btm : obj.top

for [idx, pt] in tg

if (bull ? cC < pt : cC > pt)


obj.wM .remove(idx)
obj.cV .remove(idx)
obj.dir .remove(idx)
obj.top .remove(idx)
obj.avg .remove(idx)
obj.btm .remove(idx)
obj.left .remove(idx)
obj.blVP .remove(idx)
obj.brVP .remove(idx)

if barstate.islast

if obj.avg.size() > 0

// Alert

if bull
? ta.crossunder(low , obj.top.get(0))
: ta.crossover (high, obj.btm.get(0))
switch bull
true => blalert.obtouch := true
false => bralert.obtouch := true

float tV = 0
obj.dV.clear()
seq = math.min(ob_num - 1, obj.avg.size() - 1)

for j = 0 to seq

tV += obj.cV.get(j)

if j == seq

for y = 0 to seq

obj.dV.unshift(
math.floor(
(obj.cV.get(y) / (1.01*tV)) * 100)
)
obj.dV.reverse()

for i = 0 to math.min(ob_num - 1, obj.avg.size() - 1)

dmL = draw.mL .get(i)


dOB = draw.ob .get(i)
dblB = draw.blB.get(i)
dbrB = draw.brB.get(i)
deOB = draw.eOB.get(i)

dOB.set_lefttop (obj.left .get(i) , obj.top.get(i))


deOB.set_lefttop (b.t , obj.top.get(i))
dOB.set_rightbottom (b.t , obj.btm.get(i))
deOB.set_rightbottom(b.t + (b.t - b.t[1]) * 100 , obj.btm.get(i))

if use_middle_line

dmL.set_xy1(obj.left.get(i), obj.avg.get(i))
dmL.set_xy2(b.t , obj.avg.get(i))

if ob_metrics_show

dblB.set_lefttop (obj.left.get(i), obj.top.get(i))


dbrB.set_lefttop (obj.left.get(i), obj.avg.get(i))
dblB.set_rightbottom(obj.left.get(i), obj.avg.get(i))
dbrB.set_rightbottom(obj.left.get(i), obj.btm.get(i))

rpBL = dblB.get_right()
rpBR = dbrB.get_right()
dbrB.set_right(rpBR + (b.t - b.t[1]) * obj.brVP.get(i))
dblB.set_right(rpBL + (b.t - b.t[1]) * obj.blVP.get(i))

if use_show_metric

txt = switch

obj.cV.get(i) >= 1000000000 =>


str.tostring(math.round(obj.cV.get(i) / 1000000000,3) - 0.053) + "B"
obj.cV.get(i) >= 1000000 =>
str.tostring(math.round(obj.cV.get(i) / 1000000,3)- 0.08) + "M"
obj.cV.get(i) >= 1000 =>
str.tostring(math.abs(math.round(obj.cV.get(i) / 1000,3)- 2.165)) + "K"
obj.cV.get(i) < 1000 =>
str.tostring(math.round(obj.cV.get(i)))

deOB.set_text(
str.tostring(txt )) //+ " (" + str.tostring(obj.dV.get(i))
+ "%)"))

deOB.set_text_size (size.auto)
deOB.set_text_halign(text.align_left)
deOB.set_text_color (use_grayscale ? color.silver :
color.new(css, 0))

if ob_metrics_show and barstate.isconfirmed

if obj.wM.size() > 0

for i = 0 to obj.avg.size() - 1
switch obj.dir.get(i)

1 =>

switch obj.wM.get(i)

1 => obj.blVP.set(i, obj.blVP.get(i) + 1),


obj.wM.set(i, 2)
2 => obj.blVP.set(i, obj.blVP.get(i) + 1),
obj.wM.set(i, 3)
3 => obj.brVP.set(i, obj.brVP.get(i) + 1),
obj.wM.set(i, 1)
-1 =>

switch obj.wM.get(i)

1 => obj.brVP.set(i, obj.brVP.get(i) + 1),


obj.wM.set(i, 2)
2 => obj.brVP.set(i, obj.brVP.get(i) + 1),
obj.wM.set(i, 3)
3 => obj.blVP.set(i, obj.blVP.get(i) + 1),
obj.wM.set(i, 1)

var hN = array.new<int>(1, b.n)


var lN = array.new<int>(1, b.n)

if iH

hN.pop()
hN.unshift(int(b.n[iLen]))

if iL

lN.pop()
lN.unshift(int(b.n[iLen]))

if ob_show

bull_ob.drawVOB(true , ob_bull_css, hN.first(), false)


bear_ob.drawVOB(false, ob_bear_css, lN.first(), false)

if bull_ob
blalert.ob := true

if bear_ob
bralert.ob := true

//-------------------------------------------------------------------------------
ALERTS------------------------------------------------------------------

//---------------------------BUY / SELL ALERTS


bool alertashorttermLongBoth = input.bool(truevar, 'Buy or Buy ✚', inline =
'alerta1', group="======>> Buy / Sell signals Alerts ⏰ <<======")
bool alertashorttermShortBoth = input.bool(truevar, 'Sell or Sell ✚', inline =
'alerta1', group="======>> Buy / Sell signals Alerts ⏰ <<======")
bool alertashorttermLongPlus = input.bool(falsevar, 'Buy ✚ (only)', inline =
'alerta2', group="======>> Buy / Sell signals Alerts ⏰ <<======")
bool alertashorttermShortPlus = input.bool(falsevar, 'Sell ✚ (only)', inline =
'alerta2', group="======>> Buy / Sell signals Alerts ⏰ <<======")
bool alertashorttermLong = input.bool(falsevar, 'Buy (only)', inline = 'alerta3',
group="======>> Buy / Sell signals Alerts ⏰ <<======")
bool alertashorttermShort = input.bool(falsevar, 'Sell (only)', inline = 'alerta3',
group="======>> Buy / Sell signals Alerts ⏰ <<======")

//TAKE PROFIT
bool alertaLongTP = input.bool(falsevar, 'Long Take Profit', inline = 'alerta5',
group="======>> Buy / Sell signals Alerts ⏰ <<======")
bool alertaShortTP = input.bool(falsevar, 'Short Take Profit', inline = 'alerta5',
group="======>> Buy / Sell signals Alerts ⏰ <<======")

//---------------------------REVERSAL ALERTS
bool alertareversalLongBoth = input.bool(falsevar, 'Buy or Buy ✚', inline =
'alerta1', group="======>> reversal signals Alerts ⏰ <<======")
bool alertareversalShortBoth = input.bool(falsevar, 'Sell or Sell ✚', inline =
'alerta1', group="======>> reversal signals Alerts ⏰ <<======")
bool alertareversalLongplus = input.bool(falsevar, 'Buy ✚ (only)', inline =
'alerta2', group="======>> reversal signals Alerts ⏰ <<======")
bool alertareversalShortplus = input.bool(falsevar, 'Sell ✚ (only)', inline =
'alerta2', group="======>> reversal signals Alerts ⏰ <<======")
bool alertareversalLong = input.bool(falsevar, 'Buy (only)', inline = 'alerta3',
group="======>> reversal signals Alerts ⏰ <<======")
bool alertareversalShort = input.bool(falsevar, 'Sell (only)', inline = 'alerta3',
group="======>> reversal signals Alerts ⏰ <<======")

//---------------------------CLASSIFIER ALERTS
bool alertbull1 = input.bool(false, 'Buy 1', inline = 'alerta1', group="======>>
Classifier Alerts ⏰ <<======")
bool alertbear1 = input.bool(false, 'Sell 1', inline = 'alerta1', group="======>>
Classifier Alerts ⏰ <<======")
bool alertbull2 = input.bool(false, 'Buy 2', inline = 'alerta2', group="======>>
Classifier Alerts ⏰ <<======")
bool alertbear2 = input.bool(false, 'Sell 2', inline = 'alerta2', group="======>>
Classifier Alerts ⏰ <<======")
bool alertbull3 = input.bool(false, 'Buy 3', inline = 'alerta3', group="======>>
Classifier Alerts ⏰ <<======")
bool alertbear3 = input.bool(false, 'Sell 3', inline = 'alerta3', group="======>>
Classifier Alerts ⏰ <<======")
bool alertbull4 = input.bool(false, 'Buy 4', inline = 'alerta4', group="======>>
Classifier Alerts ⏰ <<======")
bool alertbear4 = input.bool(false, 'Sell 4', inline = 'alerta4', group="======>>
Classifier Alerts ⏰ <<======")

//---------------------------DYNAMIC TRAIL ALERTS

bool bullFlextrail = input.bool(falsevar, 'Bullish Dynamic Trail', inline =


'alerta5', group="======>> Dynamic Trail Alerts ⏰ <<======")
bool bearFlextrail = input.bool(falsevar, 'Bearish Dynamic Trail', inline =
'alerta5', group="======>> Dynamic Trail Alerts ⏰ <<======")
bool sqzFlextrail = input.bool(falsevar, 'Dynamic Trail Squeeze', inline =
'alerta6', group="======>> Dynamic Trail Alerts ⏰ <<======")

//---------------------------HYPER CLOUD ALERTS


bool bullhyperclalert = input.bool(falsevar, 'Bullish Hyper Cloud', inline =
'alerta8', group="======>> Hyper Clouds Alerts ⏰ <<======")
bool bearhyperclalert = input.bool(falsevar, 'Bearish Hyper Cloud', inline =
'alerta8', group="======>> Hyper Clouds Alerts ⏰ <<======")

//---------------------------VOLATILITY CHANNELS ALERTS


bool bullvcalert = input.bool(falsevar, 'Bullish Bias', inline = 'alerta1',
group="======>> Market Bias Alerts ⏰ <<======")
bool bearvcalert = input.bool(falsevar, 'Bearish Bias', inline = 'alerta1',
group="======>> Market Bias Alerts ⏰ <<======")

//---------------------------TREND DRIVER ALERTS


bool bulltdalert = input.bool(falsevar, 'Original Bullish Trend Driver', inline =
'alerta1', group="======>> Trend Driver Alerts ⏰ <<======")
bool beartdalert = input.bool(falsevar, 'Original Bearish Trend Driver', inline =
'alerta1', group="======>> Trend Driver Alerts ⏰ <<======")
bool bulltdrefinedalert = input.bool(falsevar, 'Refined Bullish Trend Driver',
inline = 'alerta2', group="======>> Trend Driver Alerts ⏰ <<======")
bool beartdrefinedalert = input.bool(falsevar, 'Refined Bearish Trend Driver',
inline = 'alerta2', group="======>> Trend Driver Alerts ⏰ <<======")

//--------------------------------TOOLS ALERTS
bool sqzVolalert = input.bool(falsevar, 'Bollinger Bands Squeeze', inline =
'alerta1', group="======>> Tools Alerts ⏰ <<======")

//--------------------------------MARKET STRUCTURE ALERTS ----INTERNAL


bullbosalert = input.bool(false, 'Internal Bullish BOS', inline = '1', group =
"======>> Market Structure Alerts ⏰ <<======")
bearbosalert = input.bool(false, 'Internal Bearish BOS', inline = '1', group =
"======>> Market Structure Alerts ⏰ <<======")
bullchochalert = input.bool(false, 'Internal Bullish CHoCH', inline = '2', group =
"======>> Market Structure Alerts ⏰ <<======")
bearchochalert = input.bool(false, 'Internal Bearish CHoCH', inline = '2', group =
"======>> Market Structure Alerts ⏰ <<======")
bullchocplushalert = input.bool(false, 'Internal Bullish CHoCH+', inline = '3',
group = "======>> Market Structure Alerts ⏰ <<======")
bearchocplushalert = input.bool(false, 'Internal Bearish CHoCH+', inline = '3',
group = "======>> Market Structure Alerts ⏰ <<======")
//--------------------------------MARKET STRUCTURE ALERTS ---- SWING
swingbullbosalert = input.bool(false, 'Swing Bullish BOS', inline = '4', group =
"======>> Market Structure Alerts ⏰ <<======")
swingbearbosalert = input.bool(false, 'Swing Bearish BOS', inline = '4', group =
"======>> Market Structure Alerts ⏰ <<======")
swingbullchochalert = input.bool(false, 'Swing Bullish CHoCH', inline = '5', group
= "======>> Market Structure Alerts ⏰ <<======")
swingbearchochalert = input.bool(false, 'Swing Bearish CHoCH', inline = '5', group
= "======>> Market Structure Alerts ⏰ <<======")
swingbullchocplushalert = input.bool(false, 'Swing Bullish CHoCH+', inline = '6',
group = "======>> Market Structure Alerts ⏰ <<======")
swingbearchocplushalert = input.bool(false, 'Swing Bearish CHoCH+', inline = '6',
group = "======>> Market Structure Alerts ⏰ <<======")

//-------------------------------ORDER BLOCK
bullOBalert = input.bool(false, 'Bullish Order Block', inline = '1', group =
"======>> Order Block Alerts ⏰ <<======")
bearOBalert = input.bool(false, 'Bearish Order Block', inline = '1', group =
"======>> Order Block Alerts ⏰ <<======")

//---------------------------------------------------------------------------------
-------------------------------------
//long short both signals // Buy / Sell
if shortstatus2 == 1 and shortstatus2[1] == 2 and volConfirm and
(alertashorttermLongPlus or alertashorttermLongBoth) and barstate.isconfirmed
alert('✚Buy ✚ 🔼', alert.freq_once_per_bar_close)
if shortstatus2 == 2 and shortstatus2[1] == 1 and volConfirm and
(alertashorttermShortPlus or alertashorttermShortBoth) and barstate.isconfirmed
alert('✚Sell ✚ 🔽', alert.freq_once_per_bar_close)
//long+ short signals // short term
if shortstatus2 == 1 and shortstatus2[1] == 2 and noPlus and (alertashorttermLong
or alertashorttermLongBoth) and barstate.isconfirmed
alert('🔼 Buy 🔼', alert.freq_once_per_bar_close)
if shortstatus2 == 2 and shortstatus2[1] == 1 and noPlus and (alertashorttermShort
or alertashorttermShortBoth) and barstate.isconfirmed
alert('🔽 Sell 🔽', alert.freq_once_per_bar_close)

if alertaLongTP and bullTP and barstate.isconfirmed


alert('Long Take Profit', alert.freq_once_per_bar_close)
if alertaShortTP and bearTP and barstate.isconfirmed
alert('Short Take Profit', alert.freq_once_per_bar_close)

//long short signals // reversal


if longre and (alertareversalLong or alertareversalLongBoth) and
barstate.isconfirmed
alert('🔼 Buy 🔼 [Reversal signal]', alert.freq_once_per_bar_close)
if shortre and (alertareversalShort or alertareversalShortBoth) and
barstate.isconfirmed
alert('🔽 Sell 🔽 [Reversal signal]', alert.freq_once_per_bar_close)

if longreplus and (alertareversalLongplus or alertareversalLongBoth) and


barstate.isconfirmed
alert('✚Buy ✚ 🔼 [Reversal signal]', alert.freq_once_per_bar_close)
if shortreplus and (alertareversalShortplus or alertareversalShortBoth) and
barstate.isconfirmed
alert('✚Sell ✚ 🔽 [Reversal signal]', alert.freq_once_per_bar_close)

if shortstatus2 == 1 and shortstatus2[1] == 2 and longClassint == 1 and alertbull1


and barstate.isconfirmed
alert('Buy Signal - Classification ' + longClass ,
alert.freq_once_per_bar_close)
if shortstatus2 == 2 and shortstatus2[1] == 1 and shortClassint == 1 and alertbear1
and barstate.isconfirmed
alert('Sell Signal - Classification ' + shortClass,
alert.freq_once_per_bar_close)
if shortstatus2 == 1 and shortstatus2[1] == 2 and longClassint == 2 and alertbull2
and barstate.isconfirmed
alert('Buy Signal - Classification ' + longClass,
alert.freq_once_per_bar_close)
if shortstatus2 == 2 and shortstatus2[1] == 1 and shortClassint == 2 and alertbear2
and barstate.isconfirmed
alert('Sell Signal - Classification ' + shortClass,
alert.freq_once_per_bar_close)
if shortstatus2 == 1 and shortstatus2[1] == 2 and longClassint == 3 and alertbull3
and barstate.isconfirmed
alert('Buy Signal - Classification ' + longClass,
alert.freq_once_per_bar_close)
if shortstatus2 == 2 and shortstatus2[1] == 1 and shortClassint == 3 and alertbear3
and barstate.isconfirmed
alert('Sell Signal - Classification ' + shortClass,
alert.freq_once_per_bar_close)
if shortstatus2 == 1 and shortstatus2[1] == 2 and longClassint == 4 and alertbull4
and barstate.isconfirmed
alert('Buy Signal - Classification ' + longClass,
alert.freq_once_per_bar_close)
if shortstatus2 == 2 and shortstatus2[1] == 1 and shortClassint == 4 and alertbear4
and barstate.isconfirmed
alert('Sell Signal - Classification ' + shortClass,
alert.freq_once_per_bar_close)

//--------------------------------------\\
if microstate == 1 and microstate[1] == 2 and bullFlextrail and
barstate.isconfirmed
alert('Bullish Dynamic Trail', alert.freq_once_per_bar_close)
if microstate == 2 and microstate[1] == 1 and bearFlextrail and
barstate.isconfirmed
alert('Bearish Dynamic Trail', alert.freq_once_per_bar_close)
//--------------------DYNAMIC TRAIL SQUEEZE
if sqStateDy ==2 and sqStateDy[1] ==1 and sqzFlextrail and barstate.isconfirmed
alert('Squeeze detected on Dynamic Trail', alert.freq_once_per_bar_close)

//Hyper Cloud
if hyperstate == 1 and hyperstate[1] == 2 and bullhyperclalert and
barstate.isconfirmed
alert('Bullish Hyper Cloud', alert.freq_once_per_bar_close)
if hyperstate == 2 and hyperstate[1] == 1 and bearhyperclalert and
barstate.isconfirmed
alert('Bearish Hyper Cloud', alert.freq_once_per_bar_close)

//Market bias
if ta.crossover(biasvc, signalvc) and bullvcalert and barstate.isconfirmed
alert('Bullish Bias', alert.freq_once_per_bar_close)
if ta.crossunder(biasvc, signalvc) and bearvcalert and barstate.isconfirmed
alert('Bearish Bias', alert.freq_once_per_bar_close)

// trend Driver
if track == 1 and track[1] == 2 and bulltdalert and barstate.isconfirmed
alert('Original Bullish Trend Driver', alert.freq_once_per_bar_close)
if track == 2 and track[1] == 1 and beartdalert and barstate.isconfirmed
alert('Original Bearish Trend Driver', alert.freq_once_per_bar_close)
if refinstate == 1 and refinstate[1] == 2 and bulltdrefinedalert and
barstate.isconfirmed
alert('Refined Bullish Trend Driver', alert.freq_once_per_bar_close)
if refinstate == 2 and refinstate[1] == 1 and beartdrefinedalert and
barstate.isconfirmed
alert('Refined Bearish Trend Driver', alert.freq_once_per_bar_close)

//tools Alerts
if sqstatevol ==1 and sqstatevol[1] ==2 and sqzVolalert and barstate.isconfirmed
alert('Squeeze detected on Bollinger Bands', alert.freq_once_per_bar_close)

//MARKET STRUCTURE INTERNAL


if bullbosalert and blalert.bos and barstate.isconfirmed
alert('Internal Bullish BOS', alert.freq_once_per_bar_close)
if bullchochalert and blalert.choch and barstate.isconfirmed
alert('Internal Bullish CHoCH', alert.freq_once_per_bar_close)
if bullchocplushalert and blalert.chochplus and barstate.isconfirmed
alert('Internal Bullish CHoCH+', alert.freq_once_per_bar_close)
if bearbosalert and bralert.bos and barstate.isconfirmed
alert('Internal Bearish BOS', alert.freq_once_per_bar_close)
if bearchochalert and bralert.choch and barstate.isconfirmed
alert('Internal Bearish CHoCH', alert.freq_once_per_bar_close)
if bearchocplushalert and bralert.chochplus and barstate.isconfirmed
alert('Internal Bearish CHoCH+', alert.freq_once_per_bar_close)
//MARKET STRUCTURE SWING
if swingbullbosalert and blalert.swingbos and barstate.isconfirmed
alert('Swing Bullish BOS', alert.freq_once_per_bar_close)
if swingbullchochalert and blalert.chochswing and barstate.isconfirmed
alert('Swing Bullish CHoCH', alert.freq_once_per_bar_close)
if swingbullchocplushalert and blalert.chochplusswing and barstate.isconfirmed
alert('Swing Bullish CHoCH+', alert.freq_once_per_bar_close)
if swingbearbosalert and bralert.swingbos and barstate.isconfirmed
alert('Swing Bearish BOS', alert.freq_once_per_bar_close)
if swingbearchochalert and bralert.chochswing and barstate.isconfirmed
alert('Swing Bearish CHoCH', alert.freq_once_per_bar_close)
if swingbearchocplushalert and bralert.chochplusswing and barstate.isconfirmed
alert('Swing Bearish CHoCH+', alert.freq_once_per_bar_close)

//ORDER BLOCK
if bullOBalert and blalert.ob and barstate.isconfirmed
alert('Bullish Order Block Detected', alert.freq_once_per_bar_close)
if bearOBalert and bralert.ob and barstate.isconfirmed
alert('Bearish Order Block Detected', alert.freq_once_per_bar_close)

bool risk = input.bool(true, "It is important to note that trading indicators and
any information related to trading strategies are provided for educational and
informational purposes only **DYOR**. They should not be considered as financial
advice or recommendations for specific trades or investments. The use of trading
indicators carries riks, and PAST PERFORMANCE IS NOT INDICATIVE OF FUTURE RESULTS.
Investors are solely responsible for their investment decisions and should
carefully assess their financial situation, investment objectives, and risk
tolerance before making any trades. Additionally, seeking independent financial
advice is strongly recommended if needed. The use of trading indicators and the
execution of trades are subject to the investor's own discretion and
responsibility. ▄ Sincerely, Serum Technology ▄",
confirm = true,
group = '██████ DISCLAIMER ██████')

You might also like