0% found this document useful (0 votes)
778 views19 pages

Machine Learning KNN Based With Support and Resistance

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)
778 views19 pages

Machine Learning KNN Based With Support and Resistance

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/ 19

// This source code is subject to the terms of the Mozilla Public License 2.

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

//@version=5
indicator('Machine Learning: kNN-based Strategy', 'ML-kNN', true,
max_labels_count=300, format=format.price, precision=2)

//-- Preset Dates

int startdate = timestamp('01 Jan 2000 00:00:00 GMT+10')


int stopdate = timestamp('31 Dec 2025 23:45:00 GMT+10')

//-- Inputs

StartDate = input.time (startdate, 'Start Date')


StopDate = input.time (stopdate, 'Stop Date')
Indicator = input.string('All', 'Indicator',
['RSI','ROC','CCI','Volume','All'])
ShortWinow = input.int (14, 'Short Period [1..n]', 1)
LongWindow = input.int (28, 'Long Period [2..n]', 2)
BaseK = input.int (252, 'Base No. of Neighbours (K) [5..n]', 5)
Filter = input.bool (false, 'Volatility Filter')
Bars = input.int (300, 'Bar Threshold [2..5000]', 2, 5000)

//-- Constants

var int BUY = 1


var int SELL =-1
var int CLEAR = 0

var int k = math.floor(math.sqrt(BaseK)) // k Value for kNN algo

//-- Variable

// Training data, normalized to the range of [0,...,100]


var array<float> feature1 = array.new_float(0) // [0,...,100]
var array<float> feature2 = array.new_float(0) // ...
var array<int> directions = array.new_int(0) // [-1; +1]

// Result data
var array<int> predictions = array.new_int(0)
var float prediction = 0.0
var array<int> bars = array.new<int>(1, 0) // array used as a container
for inter-bar variables

// Signals
var int signal = CLEAR

//-- Functions

minimax(float x, int p, float min, float max) =>


float hi = ta.highest(x, p), float lo = ta.lowest(x, p)
(max - min) * (x - lo)/(hi - lo) + min

cAqua(int g) => g>9?#0080FFff:g>8?#0080FFe5:g>7?#0080FFcc:g>6?#0080FFb2:g>5?


#0080FF99:g>4?#0080FF7f:g>3?#0080FF66:g>2?#0080FF4c:g>1?#0080FF33:#00C0FF19
cPink(int g) => g>9?#FF0080ff:g>8?#FF0080e5:g>7?#FF0080cc:g>6?#FF0080b2:g>5?
#FF008099:g>4?#FF00807f:g>3?#FF008066:g>2?#FF00804c:g>1?#FF008033:#FF008019

inside_window(float start, float stop) =>


time >= start and time <= stop ? true : false

//-- Logic

bool window = inside_window(StartDate, StopDate)

// 3 pairs of predictor indicators, long and short each


float rs = ta.rsi(close, LongWindow), float rf = ta.rsi(close,
ShortWinow)
float cs = ta.cci(close, LongWindow), float cf = ta.cci(close,
ShortWinow)
float os = ta.roc(close, LongWindow), float of = ta.roc(close,
ShortWinow)
float vs = minimax(volume, LongWindow, 0, 99), float vf = minimax(volume,
ShortWinow, 0, 99)

// TOADD or TOTRYOUT:
// ta.cmo(close, LongWindow), ta.cmo(close, ShortWinow)
// ta.mfi(close, LongWindow), ta.mfi(close, ShortWinow)
// ta.mom(close, LongWindow), ta.mom(close, ShortWinow)

float f1 = switch Indicator


'RSI' => rs
'CCI' => cs
'ROC' => os
'Volume' => vs
=> math.avg(rs, cs, os, vs)

float f2 = switch Indicator


'RSI' => rf
'CCI' => cf
'ROC' => of
'Volume' => vf
=> math.avg(rf, cf, of, vf)

// Classification data, what happens on the next bar


int class_label = int(math.sign(close[1] - close[0])) // eq. close[1]<close[0] ?
SELL: close[1]>close[0] ? BUY : CLEAR

// Use particular training period


if window
// Store everything in arrays. Features represent a square 100 x 100 matrix,
// whose row-colum intersections represent class labels, showing historic
directions
array.push(feature1, f1)
array.push(feature2, f2)
array.push(directions, class_label)

// Ucomment the followng statement (if barstate.islast) and tab everything below
// between BOBlock and EOBlock marks to see just the recent several signals
gradually
// showing up, rather than all the preceding signals

//if barstate.islast

//==BOBlock
// Core logic of the algorithm
int size = array.size(directions)
float maxdist = -999.0
// Loop through the training arrays, getting distances and corresponding
directions.
for i=0 to size-1
// Calculate the euclidean distance of current point to all historic points,
// here the metric used might as well be a manhattan distance or any other.
float d = math.sqrt(math.pow(f1 - array.get(feature1, i), 2) + math.pow(f2 -
array.get(feature2, i), 2))

if d > maxdist
maxdist := d
if array.size(predictions) >= k
array.shift(predictions)
array.push(predictions, array.get(directions, i))

//==EOBlock

// Note: in this setup there's no need for distances array (i.e.


array.push(distances, d)),
// but the drawback is that a sudden max value may shadow all the subsequent
values.
// One of the ways to bypass this is to:
// 1) store d in distances array,
// 2) calculate newdirs = bubbleSort(distances, directions), and then
// 3) take a slice with array.slice(newdirs) from the end

// Get the overall prediction of k nearest neighbours


prediction := array.sum(predictions)

bool filter = Filter ? ta.atr(10) > ta.atr(40) : true // filter out by volatility
or ex. ta.atr(1) > ta.atr(10)...

// Now that we got a prediction for the next market move, we need to make use of
this prediction and
// trade it. The returns then will show if everything works as predicted.
// Over here is a simple long/short interpretation of the prediction,
// but of course one could also use the quality of the prediction (+5 or +1) in
some sort of way,
// ex. for position sizing.

bool long = prediction > 0 and filter


bool short = prediction < 0 and filter
bool clear = not(long and short)

if array.get(bars, 0)==Bars // stop by trade duration


signal := CLEAR
array.set(bars, 0, 0)
else
array.set(bars, 0, array.get(bars, 0) + 1)

signal := long ? BUY : short ? SELL : clear ? CLEAR : nz(signal[1])

int changed = ta.change(signal)


bool startLongTrade = changed and signal==BUY
bool startShortTrade = changed and signal==SELL
// bool endLongTrade = changed and signal==SELL
// bool endShortTrade = changed and signal==BUY
bool clear_condition = changed and signal==CLEAR //or (changed and signal==SELL) or
(changed and signal==BUY)

float maxpos = ta.highest(high, 10)


float minpos = ta.lowest (low, 10)

//-- Visuals

plotshape(startLongTrade ? minpos : na, 'Buy', shape.labelup,


location.belowbar, cAqua(int(prediction*5)), size=size.small) // color intensity
correction
plotshape(startShortTrade ? maxpos : na, 'Sell', shape.labeldown,
location.abovebar, cPink(int(-prediction*5)), size=size.small)
// plot(endLongTrade ? ohlc4 : na, 'StopBuy', cAqua(6), 3,
plot.style_cross)
// plot(endShortTrade ? ohlc4 : na, 'StopSell', cPink(6), 3,
plot.style_cross)
plot(clear_condition ? close : na, 'ClearPos', color.yellow, 4,
plot.style_cross)

//-- Notification

// if changed and signal==BUY


// alert('Buy Alert', alert.freq_once_per_bar) //
alert.freq_once_per_bar_close
// if changed and signal==SELL
// alert('Sell Alert', alert.freq_once_per_bar)

alertcondition(startLongTrade, 'Buy', 'Go long!')


alertcondition(startShortTrade, 'Sell', 'Go short!')
//alertcondition(startLongTrade or startShortTrade, 'Alert', 'Deal Time!')

//-------------------- Backtesting (TODO)

// show_cumtr = input.bool (false, 'Show Trade Return?')


// lot_size = input.float(100.0, 'Lot Size',
[0.1,0.2,0.3,0.5,1,2,3,5,10,20,30,50,100,1000,2000,3000,5000,10000])

// var start_lt = 0.
// var long_trades = 0.
// var start_st = 0.
// var short_trades = 0.

// if startLongTrade
// start_lt := ohlc4
// if endLongTrade
// long_trades := (open - start_lt) * lot_size
// if startShortTrade
// start_st := ohlc4
// if endShortTrade
// short_trades := (start_st - open) * lot_size

// cumreturn = ta.cum(long_trades) + ta.cum(short_trades)

// var label lbl = na


// if show_cumtr //and barstate.islast
// lbl := label.new(bar_index+10, close, 'CumReturn: ' +
str.tostring(cumreturn, '#.#'), xloc.bar_index, yloc.price,
// color.new(color.blue, 100), label.style_label_left,
color.black, size.small, text.align_left)
// label.delete(lbl[1])

//------------------------------------------------------------------------------
// Settings
//-----------------------------------------------------------------------------{

srGR = 'Support & Resistance Settings'


srTT = 'tip : in ranging markets higher timeframe resolution or higher detection
length might help reduce the noise'
srTF = input.string('Chart', 'Detection Timeframe', options=['Chart', '15
Minutes', '1 Hour', '4 Hours', '1 Day', '1 Week'], group = srGR, tooltip = srTT)
srLN = input(15, 'Detection Length', group = srGR)

srMR = input.float(2, 'Support Resistance Margin', minval = .1, maxval = 10, step
= .1, group = srGR)

srSLC = input(color.new(#089981, 53), ' - Support, Lines', inline = 'srS',


group = srGR)
srSZC = input(color.new(#089981, 83), 'Zones', inline = 'srS', group = srGR)
srRLC = input(color.new(#f23645, 53), ' - Resistance, Lines', inline = 'srR',
group = srGR)
srRZC = input(color.new(#f23645, 83), 'Zones', inline = 'srR', group = srGR)

srHST = input.bool(true, 'Check Previous Historical S&R Zone', group = srGR)

mnGR = 'Manupulations'
mnSH = input.bool(true, 'Manupulation Zones', group = mnGR)
mnMR = input.float(1.3, 'Manupulation Margin', minval = .1, maxval = 10, step
= .1, group = mnGR)
mnSZC = input(color.new(#2962ff, 73), 'Manupulation Zones, Support', inline =
'LQ', group = mnGR)
mnRZC = input(color.new(#ff9800, 73), 'Resistance', inline = 'LQ', group = mnGR)

sigGR = 'Signals'
srFBT = 'Filters the breakouts that failed to continue beyond a level'
srFBO = input.bool(true, 'Avoid False Breakouts', group = sigGR, tooltip = srFBT)

srBUC = input(color.new(#089981, 33), 'Breakouts, Bullish', inline = 'srB', group


= sigGR)
srBDC = input(color.new(#f23645, 33), 'Bearish', inline = 'srB', group = sigGR)
srBS = input.string('Tiny', "", options=['Auto', 'Tiny', 'Small', 'Normal',
'None'], inline = 'srB', group = sigGR)

srTUC = input(color.new(#2962ff, 33), 'Tests, Bullish', inline = 'srT', group


= sigGR)
srTDC = input(color.new(#e040fb, 33), 'Bearish', inline = 'srT', group = sigGR)
srTS = input.string('Tiny', "", options=['Auto', 'Tiny', 'Small', 'Normal',
'None'], inline = 'srT', group = sigGR)

srRUC = input(color.new(#089981, 33), 'Retests, Bullish', inline = 'srR', group


= sigGR)
srRDC = input(color.new(#f23645, 33), 'Bearish', inline = 'srR', group = sigGR)
srRS = input.string('Tiny', "", options=['Auto', 'Tiny', 'Small', 'Normal',
'None'], inline = 'srR', group = sigGR)
srPUC = input(color.new(#089981, 33), 'Rejections, Bullish', inline = 'srP', group
= sigGR)
srPDC = input(color.new(#f23645, 33), 'Bearish', inline = 'srP', group = sigGR)
srPS = input.string('Tiny', "", options=['Auto', 'Tiny', 'Small', 'Normal',
'None'], inline = 'srP', group = sigGR)

othGR = 'Others'
swSH = input.string('None', "Swing Levels", options=['Auto', 'Small', 'Normal',
'Large', 'None'], inline = 'sw', group = othGR)
swHC = input(color.new(#f23645, 33), 'H', inline = 'sw', group = othGR)
swLC = input(color.new(#089981, 33), 'L', inline = 'sw', group = othGR)

//-----------------------------------------------------------------------------}
// User Defined Types
//-----------------------------------------------------------------------------{

// @type bar properties with their values


//
// @field o (float) open price of the bar
// @field h (float) high price of the bar
// @field l (float) low price of the bar
// @field c (float) close price of the bar
// @field v (float) volume of the bar
// @field i (int) index of the bar

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

// @type store pivot high/low and index data


//
// @field x (int) last pivot bar index
// @field x1 (int) previous pivot bar index
// @field h (float) last pivot high
// @field h1 (float) previous pivot high
// @field l (float) last pivot low
// @field l1 (float) previous pivot low
// @field hx (bool) pivot high cross status
// @field lx (bool) pivot low cross status

type pivotPoint
int x
int x1
float h
float h1
float l
float l1
bool hx
bool lx

// @type stores support and resistance visuals and signal status


//
// @field bx (box) support and resistance zones
// @field lq (box) liquidity sweeps
// @field ln (line) support and resistance levels
// @field b (bool) breakout status
// @field b (bool) test status
// @field b (bool) retest status
// @field b (bool) liqudation status
// @field m (float) default margin

type SnR
box bx
box lq
line ln
bool b
bool t
bool r
bool l
float m

//-----------------------------------------------------------------------------}
// Variables
//-----------------------------------------------------------------------------{

bar b = bar.new()

var pivotPoint pp = pivotPoint.new()

var SnR[] R = array.new<SnR> (1, SnR.new(box(na), box(na), line(na), false, false,


false, false, na))
var SnR[] S = array.new<SnR> (1, SnR.new(box(na), box(na), line(na), false, false,
false, false, na))

var SnR lR = SnR.new(box(na), box(na), line(na), false, false, false, false, na)
var SnR lS = SnR.new(box(na), box(na), line(na), false, false, false, false, na)
var SnR lRt = SnR.new(box(na), box(na), line(na), false, false, false, false, na)
var SnR lSt = SnR.new(box(na), box(na), line(na), false, false, false, false, na)

var int mss = 0

//-----------------------------------------------------------------------------}
// General Calculations
//-----------------------------------------------------------------------------{

int tf_m = switch srTF


"Chart" => timeframe.isintraday ? timeframe.multiplier : timeframe.isdaily
? 1440 : timeframe.isweekly ? 10080 : 10080 * 30
"15 Minutes" => 15
"1 Hour" => 60
"4 Hours" => 240
"1 Day" => 1440
"1 Week" => 10080

ch_m = if timeframe.isintraday
timeframe.multiplier
else if timeframe.isdaily
1440
else if timeframe.isweekly
10080
else if timeframe.ismonthly
10080 * 30

srLN := srLN * tf_m / ch_m


pHST = ta.highest(b.h, srLN)
pLST = ta.lowest (b.l, srLN)

atr = ta.atr(17)
isLLS = math.abs(b.l - math.min(b.o, b.c)) >= 1.618 * atr
isLUS = math.abs(b.h - math.max(b.o, b.c)) >= 1.618 * atr

vSMA = ta.sma(nz(b.v), 17)


isHV = nz(b.v) >= 1.618 * vSMA
isLV = nz(b.v) <= 0.618 * vSMA
vST = isHV ? '\n *High Trading Activity' : isLV ? '\n *Low Trading Activity' : '\
n *Average Trading Activity'

srBUC := srBS != 'None' ? srBUC : color(na)


srBDC := srBS != 'None' ? srBDC : color(na)
srBTC = srBS != 'None' ? color.white : color(na)

srTUC := srTS != 'None' ? srTUC : color(na)


srTDC := srTS != 'None' ? srTDC : color(na)
srTTC = srTS != 'None' ? color.white : color(na)

srRUC := srRS != 'None' ? srRUC : color(na)


srRDC := srRS != 'None' ? srRDC : color(na)
srRTC = srRS != 'None' ? color.white : color(na)

//-----------------------------------------------------------------------------}
// Functions/Methods
//-----------------------------------------------------------------------------{

// @function calcuates cumulative volume of the given range


//
// @param _l (int) length of the range
// @param _o (int) offset
//
// @returns (float) cumulative volume

f_getTradedVolume(_l, _o) =>


v = 0.
for x = 0 to _l - 1
v += volume[_o + x]
v

// @function converts size strings to enumerated values


//
// @param _l (string) size string
//
// @returns (enumeration) size enumerated value

f_getSize(_s) =>
switch _s
'Tiny' => size.tiny
'Small' => size.small
'Normal' => size.normal
'Large' => size.large
'Huge' => size.huge
=> size.auto
//-----------------------------------------------------------------------------}
// Calculations
//-----------------------------------------------------------------------------{

pp_h = ta.pivothigh(srLN, srLN)

if not na(pp_h)
pp.h1 := pp.h
pp.h := pp_h
pp.x1 := pp.x
pp.x := b.i[srLN]
pp.hx := false

if R.size() > 1
lR := R.get(0)
lRt := R.get(1)

if pp.h < lR.bx.get_bottom() * (1 - lR.m * .17 * srMR) or pp.h >


lR.bx.get_top() * (1 + lR.m * .17 * srMR)
if pp.x < lR.bx.get_left() and pp.x + srLN > lR.bx.get_left() and b.c <
lR.bx.get_bottom()
na
else
if pp.h < lRt.bx.get_bottom() * (1 - lRt.m * .17 * srMR) or pp.h >
lRt.bx.get_top() * (1 + lRt.m * .17 * srMR)

R.unshift(
SnR.new(
box.new(pp.x, pp.h, b.i, pp.h * (1 - ((pHST - pLST) /
pHST) * .17 * srMR), border_color = color(na), bgcolor = srRZC),
box.new(na, na, na, na, bgcolor = color(na), border_color
= color(na)),
line.new(pp.x, pp.h, b.i, pp.h, color = srRLC, width =
srMR <= .5 ? 2 : 3),
false, false, false, false, (pHST - pLST) / pHST))

lS.t := false
else
lRt.bx.set_right(b.i)
lRt.ln.set_x2(b.i)

else if lR.bx.get_top() != lS.bx.get_top()


lR.bx.set_right(b.i)
lR.ln.set_x2(b.i)
else
R.unshift(
SnR.new(
box.new(pp.x, pp.h, b.i, pp.h * (1 - ((pHST - pLST) / pHST) * .17 *
srMR), border_color = color(na), bgcolor = srRZC),
//box.new(pp.x, pp.h, b.i, pp.h * (1 - ((pHST - pLST) / pHST) * .17 *
srMR), border_color = color(na), bgcolor = color.new(color.orange, 89)),
box.new(na, na, na, na, bgcolor = color(na), border_color =
color(na)),
line.new(pp.x, pp.h, b.i, pp.h, color = srRLC, width = srMR <= .5 ?
2 : 3),
false, false, false, false, (pHST - pLST) / pHST))

lS.t := false
if swSH != 'None'
StS = pp.x - pp.x1
tradedVolume = f_getTradedVolume(StS, srLN)
swH = pp.h > pp.h1 ? "Higher High" : pp.h < pp.h1 ? "Lower High" : na
rTT = 'Swing High (' + swH + ') : ' + str.tostring(pp.h, format.mintick) +
(mss == -1 and pp.h < pp.h1 ? '\n *Counter-Trend Move' : '') +
'\n -Price Change : ↑ %' + str.tostring((pp.h - pp.l) * 100 / pp.l ,
'#.##') +
(nz(b.v) ? '\n -Traded Volume : ' + str.tostring(tradedVolume,
format.volume) + ' (' + str.tostring(StS - 1) + ' bars)' +
'\n *Average Volume/Bar : ' + str.tostring(tradedVolume / (StS -
1), format.volume) : '')
label.new(pp.x, pp.h, '◈', color = color(na), style =
label.style_label_down, textcolor = swHC, size = f_getSize(swSH), tooltip = rTT)

alert('New ' + swH + (mss == -1 and pp.h < pp.h1 ? ' (counter-trend
move)' : '') + ' formed\n' + syminfo.ticker + ' price (' + str.tostring(b.c,
format.mintick) + '), timeframe ' + timeframe.period)

if b.c[1] > pp.h and b.c > pp.h and not pp.hx
pp.hx := true
mss := 1

pp_l = ta.pivotlow (srLN, srLN)

if not na(pp_l)
pp.l1 := pp.l
pp.l := pp_l
pp.x1 := pp.x
pp.x := b.i[srLN]
pp.lx := false

if S.size() > 2
lS := S.get(0)
lSt := S.get(1)

if pp.l < lS.bx.get_bottom() * (1 - lS.m * .17 * srMR) or pp.l >


lS.bx.get_top() * (1 + lS.m * .17 * srMR)
if pp.x < lS.bx.get_left() and pp.x + srLN > lS.bx.get_left() and b.c >
lS.bx.get_top() //not lR.b
na
else
if pp.l < lSt.bx.get_bottom() * (1 - lSt.m * .17 * srMR) or pp.l >
lSt.bx.get_top() * (1 + lSt.m * .17 * srMR)

S.unshift(
SnR.new(
box.new(pp.x, pp.l * (1 + ((pHST - pLST) / pHST) * .17 *
srMR), b.i, pp.l, border_color = color(na), bgcolor = srSZC),
box.new(na, na, na, na, bgcolor = color(na), border_color
= color(na)),
line.new(pp.x, pp.l, b.i, pp.l, color = srSLC, width =
srMR <= .5 ? 2 : 3),
false, false, false, false, (pHST - pLST) / pHST))

lR.t := false
else
lSt.bx.set_right(b.i)
lSt.ln.set_x2(b.i)

else if lS.bx.get_bottom() != lR.bx.get_bottom()


lS.bx.set_right(b.i)
lS.ln.set_x2(b.i)
else
S.unshift(
SnR.new(
box.new(pp.x, pp.l * (1 + ((pHST - pLST) / pHST) * .17 * srMR), b.i,
pp.l, border_color = color(na), bgcolor = srSZC),
//box.new(pp.x, pp.l * (1 + ((pHST - pLST) / pHST) * .17 * srMR), b.i,
pp.l, border_color = color(na), bgcolor = color.new(color.aqua, 89)),
box.new(na, na, na, na, bgcolor = color(na), border_color =
color(na)),
line.new(pp.x, pp.l, b.i, pp.l, color = srSLC, width = srMR <= .5 ?
2 : 3),
false, false, false, false, (pHST - pLST) / pHST))

lR.t := false

if swSH != 'None'
StS = pp.x - pp.x1
tradedVolume = f_getTradedVolume(StS, srLN)
swL = pp.l < pp.l1 ? "Lower Low" : pp.l > pp.l1 ? "Higher Low" : na
sTT = 'Swing Low (' + swL + ') : ' + str.tostring(pp.l, format.mintick) +
(mss == 1 and pp.l > pp.l1 ? '\n *Counter-Trend Move' : '') +
'\n -Price Change : ↓ %' + str.tostring((pp.h - pp.l) * 100 / pp.h ,
'#.##') +
(nz(b.v) ? '\n -Traded Volume : ' + str.tostring(tradedVolume,
format.volume) + ' (' + str.tostring(StS - 1) + ' bars)' +
'\n *Average Volume/Bar : ' + str.tostring(tradedVolume / (StS -
1), format.volume) : '')
label.new(pp.x, pp.l, '◈', color = color(na), style = label.style_label_up,
textcolor = swLC, size = f_getSize(swSH), tooltip = sTT)

alert('New ' + swL + (mss == 1 and pp.l > pp.l1 ? ' (counter-trend move)' :
'') + ' formed\n' + syminfo.ticker + ' price (' + str.tostring(b.c, format.mintick)
+ '), timeframe ' + timeframe.period)

if b.c[1] < pp.l and b.c < pp.l and not pp.lx
pp.lx := true
mss := -1

if R.size() > 0
lR := R.get(0)

if srFBO and b.c[1] > lR.bx.get_top() * (1 + lR.m * .17) and not lR.b
lR.bx.set_right(b.i[1])
lR.ln.set_x2(b.i[1])
lR.b := true
lR.r := false

label.new(b.i[1], b.l[1] * (1 - lR.m * .017), '▲\n\nB', color = srBUC,


style = label.style_label_up , textcolor = srBTC, size = f_getSize(srBS), tooltip =
'Bullish Breakout' + vST[1])
//label.new(b.i[1], b.l[1] * (1 - lR.m * .017), '▲\n\nB', color =
color.yellow, style = label.style_label_up , textcolor = srBTC, size =
f_getSize(srBS), tooltip = 'Bullish Breakout' + vST[1])
S.unshift(
SnR.new(
box.new(b.i[1], lR.bx.get_top(), b.i + 1, lR.bx.get_bottom(),
border_color = color(na), bgcolor = srSZC),
box.new(na, na, na, na, bgcolor = color(na), border_color =
color(na)),
line.new(b.i[1], lR.bx.get_bottom(), b.i + 1, lR.bx.get_bottom(),
color = srSLC, width = srMR <= .5 ? 2 : 3),
false, false, false, false, lR.m))
//R.remove(0)

if srBS != 'None'
alert('Bullish breakout detected\n' + syminfo.ticker + ' price (' +
str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period)

else if b.c[1] > lR.bx.get_top() and not lR.b and not srFBO
lR.bx.set_right(b.i[1])
lR.ln.set_x2(b.i[1])
lR.b := true
lR.r := false

label.new(b.i[1], b.l[1] * (1 - lR.m * .017), '▲\n\nB', color = srBUC,


style = label.style_label_up , textcolor = srBTC, size = f_getSize(srBS), tooltip =
'Bullish Breakout' + vST[1])

S.unshift(
SnR.new(
box.new(b.i[1], lR.bx.get_top(), b.i + 1, lR.bx.get_bottom(),
border_color = color(na), bgcolor = srSZC),
box.new(na, na, na, na, bgcolor = color(na), border_color =
color(na)),
line.new(b.i[1], lR.bx.get_bottom(), b.i + 1, lR.bx.get_bottom(),
color = srSLC, width = srMR <= .5 ? 2 : 3),
false, false, false, false, lR.m))
//R.remove(0)

if srBS != 'None'
alert('Bullish breakout detected\n' + syminfo.ticker + ' price (' +
str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period)

else if lS.b and b.o[1] < lR.bx.get_top() and b.h[1] > lR.bx.get_bottom() and
b.c[1] < lR.bx.get_bottom() and not lR.r and b.i[1] != lR.bx.get_left()
label.new(b.i[1], b.h[1] * (1 + lR.m * .017), 'R', color = srRDC, style =
label.style_label_down , textcolor = srRTC, size = f_getSize(srRS), tooltip = 'Re-
test of Resistance Zone' + vST[1] )
lR.r := true //
lR.bx.set_right(b.i)
lR.ln.set_x2(b.i)

if srRS != 'None'
alert('Re-test of resistance zone detected\n' + syminfo.ticker + '
price (' + str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period)

else if b.h[1] > lR.bx.get_bottom() and b.c[1] < lR.bx.get_top() and b.c <
lR.bx.get_top() and not lR.t and not lR.r and not lR.b and not lS.b and b.i[1] !=
lR.bx.get_left()
label.new(b.i[1], b.h[1] * (1 + lR.m * .017), 'T', color = srTDC, style =
label.style_label_down , textcolor = srTTC, size = f_getSize(srTS), tooltip = 'Test
of Resistance Zone' + vST[1] )
lR.t := true
lR.bx.set_right(b.i)
lR.ln.set_x2(b.i)

if srTS != 'None'
alert('Test of resistance zone detected\n' + syminfo.ticker + ' price
(' + str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period,
alert.freq_once_per_bar_close)

else if b.h > lR.bx.get_bottom() * (1 - lR.m * .17) and not lR.b //and
lR.bx.get_top() != lS.bx.get_top()
if b.h > lR.bx.get_bottom()
lR.bx.set_right(b.i)
lR.ln.set_x2(b.i)

if isLLS[1] and isHV[1] and srPS != 'None'


label.new(b.i[1], b.l[1] * (1 - lR.m * .017), '', color = srPUC, style =
label.style_label_up , textcolor = color.white, size = f_getSize(srPS), tooltip =
'Rejection of Lower Prices' + vST[1])
alert('Rejection of lower prices detected\n' + syminfo.ticker + ' price ('
+ str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period)

if mnSH
if b.h > lR.bx.get_top() and b.c <= lR.bx.get_top() * (1 + lR.m * .17 *
mnMR) and not lR.l and b.i == lR.bx.get_right()
if lR.lq.get_right() + srLN > b.i
lR.lq.set_right(b.i + 1)
lR.lq.set_top(math.min(math.max(b.h, lR.lq.get_top()),
lR.bx.get_top() * (1 + lR.m * .17 * mnMR)))
else
lR.lq.set_lefttop(b.i[1], math.min(b.h, lR.bx.get_top() * (1 + lR.m
* .17 * mnMR)))
lR.lq.set_rightbottom(b.i + 1, lR.bx.get_top())
lR.lq.set_bgcolor(mnRZC)

lR.l := true

else if b.h > lR.bx.get_top() and b.c <= lR.bx.get_top() * (1 + lR.m * .17
* mnMR) and lR.l and b.i == lR.bx.get_right()
lR.lq.set_right(b.i + 1)
lR.lq.set_top(math.min(math.max(b.h,lR.lq.get_top()), lR.bx.get_top() *
(1 + lR.m * .17 * mnMR)))
else if lR.l and (b.c >= lR.bx.get_top() * (1 + lR.m * .17 * mnMR) or b.c <
lR.bx.get_bottom())
lR.l := false

if R.size() > 1 and srHST //and (lR.b or lS.b)// and lR.bx.get_top() !=


lS.bx.get_top()
lRt := R.get(1)

if lR.bx.get_top() != lRt.bx.get_top()

if srFBO and b.c[1] > lRt.bx.get_top() * (1 + lRt.m * .17) and not lRt.b
lRt.bx.set_right(b.i[1])
lRt.ln.set_x2(b.i[1])
lRt.b := true
lRt.r := false

label.new(b.i[1], b.l[1] * (1 - lRt.m * .017), '▲\n\nB', color = srBUC,


style = label.style_label_up , textcolor = srBTC, size = f_getSize(srBS), tooltip =
'Bullish Breakout' + vST[1])

S.unshift(
SnR.new(
box.new(b.i[1], lRt.bx.get_top(), b.i + 1, lRt.bx.get_bottom(),
border_color = color(na), bgcolor = srSZC),
box.new(na, na, na, na, bgcolor = color(na), border_color =
color(na)),
line.new(b.i[1], lRt.bx.get_bottom(), b.i + 1,
lRt.bx.get_bottom(), color = srSLC, width = srMR <= .5 ? 2 : 3),
false, false, false, false, lRt.m))
//R.remove(1)

if srBS != 'None'
alert('Bullish breakout detected\n' + syminfo.ticker + ' price (' +
str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period)

else if b.c[1] > lRt.bx.get_top() and not lRt.b and not srFBO
lRt.bx.set_right(b.i[1])
lRt.ln.set_x2(b.i[1])
lRt.b := true
lRt.r := false

label.new(b.i[1], b.l[1] * (1 - lRt.m * .017), '▲\n\nB', color = srBUC,


style = label.style_label_up , textcolor = srBTC, size = f_getSize(srBS), tooltip =
'Bullish Breakout' + vST[1])

S.unshift(
SnR.new(
box.new(b.i[1], lRt.bx.get_top(), b.i + 1, lRt.bx.get_bottom(),
border_color = color(na), bgcolor = srSZC),
box.new(na, na, na, na, bgcolor = color(na), border_color =
color(na)),
line.new(b.i[1], lRt.bx.get_bottom(), b.i + 1,
lRt.bx.get_bottom(), color = srSLC, width = srMR <= .5 ? 2 : 3),
false, false, false, false, lRt.m))
//R.remove(1)

if srBS != 'None'
alert('Bullish breakout detected\n' + syminfo.ticker + ' price (' +
str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period)

else if lSt.b and b.o[1] < lRt.bx.get_top() and b.h[1] >


lRt.bx.get_bottom() and b.c[1] < lRt.bx.get_bottom() and not lRt.r and b.i[1] !=
lRt.bx.get_left()
label.new(b.i[1], b.h[1] * (1 + lRt.m * .017), 'R', color = srRDC,
style = label.style_label_down , textcolor = srRTC, size = f_getSize(srRS), tooltip
= 'Re-test of Resistance Zone' + vST[1] )
lRt.r := true //
lRt.bx.set_right(b.i)
lRt.ln.set_x2(b.i)

if srRS != 'None'
alert('Re-test of resistance zone detected\n' + syminfo.ticker + '
price (' + str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period)

else if b.h[1] > lRt.bx.get_bottom() and b.c[1] < lRt.bx.get_top() and b.c
< lRt.bx.get_top() and not lRt.t and not lRt.b and not lSt.b and b.i[1] !=
lRt.bx.get_left()
label.new(b.i[1], b.h[1] * (1 + lRt.m * .017), 'T', color = srTDC,
style = label.style_label_down , textcolor = srTTC, size = f_getSize(srTS), tooltip
= 'Test of Resistance Zone' + vST[1] )
lRt.t := true
lRt.bx.set_right(b.i)
lRt.ln.set_x2(b.i)

if srTS != 'None'
alert('Test of resistance zone detected\n' + syminfo.ticker + '
price (' + str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period,
alert.freq_once_per_bar_close)

else if b.h > lRt.bx.get_bottom() * (1 - lRt.m * .17) and not lRt.b


if b.h > lRt.bx.get_bottom()
lRt.bx.set_right(b.i)
lRt.ln.set_x2(b.i)

if mnSH
if b.h > lRt.bx.get_top() and b.c <= lRt.bx.get_top() * (1 + lRt.m
* .17 * mnMR) and not lRt.l and b.i == lRt.bx.get_right()
if lRt.lq.get_right() + srLN > b.i
lRt.lq.set_right(b.i + 1)
lRt.lq.set_top(math.min(math.max(b.h, lRt.lq.get_top()),
lRt.bx.get_top() * (1 + lRt.m * .17 * mnMR)))
else
lRt.lq.set_lefttop(b.i[1], math.min(b.h, lRt.bx.get_top() * (1
+ lRt.m * .17 * mnMR)))
lRt.lq.set_rightbottom(b.i + 1, lRt.bx.get_top())
lRt.lq.set_bgcolor(mnRZC)

lRt.l := true

else if b.h > lRt.bx.get_top() and b.c <= lRt.bx.get_top() * (1 + lRt.m


* .17 * mnMR) and lRt.l and b.i == lRt.bx.get_right()
lRt.lq.set_right(b.i + 1)
lRt.lq.set_top(math.min(math.max(b.h, lRt.lq.get_top()),
lRt.bx.get_top() * (1 + lRt.m * .17 * mnMR)))
else if lRt.l and (b.c >= lRt.bx.get_top() * (1 + lRt.m * .17 * mnMR)
or b.c < lRt.bx.get_bottom())
lRt.l := false

if S.size() > 1
lS := S.get(0)

if srFBO and b.c[1] < lS.bx.get_bottom() * (1 - lS.m * .17) and not lS.b
lS.bx.set_right(b.i[1])
lS.ln.set_x2(b.i[1])
lS.b := true
lS.r := false

label.new(b.i[1], b.h[1] * (1 + lS.m * .017), 'B\n\n▼', color = srBDC,


style = label.style_label_down , textcolor = srBTC, size = f_getSize(srBS), tooltip
= 'Bearish Breakout' + vST[1] )
//label.new(b.i[1], b.h[1] * (1 + lS.m * .017), 'B\n\n▼', color =
color.yellow, style = label.style_label_down , textcolor = srBTC, size =
f_getSize(srBS), tooltip = 'Bearish Breakout' + vST[1] )

R.unshift(
SnR.new(
box.new(b.i[1], lS.bx.get_top(), b.i + 1, lS.bx.get_bottom(),
border_color = color(na), bgcolor = srRZC),
box.new(na, na, na, na, bgcolor = color(na), border_color =
color(na)),
line.new(b.i[1], lS.bx.get_top(), b.i + 1, lS.bx.get_top(), color =
srRLC, width = srMR <= .5 ? 2 : 3),
false, false, false, false, lS.m))
//S.remove(0)

if srBS != 'None'
alert('Bearish breakout detected\n' + syminfo.ticker + ' price (' +
str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period)

if b.c[1] < lS.bx.get_bottom() and not lS.b and not srFBO


lS.bx.set_right(b.i[1])
lS.ln.set_x2(b.i[1])
lS.b := true
lS.r := false

label.new(b.i[1], b.h[1] * (1 + lS.m * .017), 'B\n\n▼', color = srBDC,


style = label.style_label_down , textcolor = srBTC, size = f_getSize(srBS), tooltip
= 'Bearish Breakout' + vST[1] )

R.unshift(
SnR.new(
box.new(b.i[1], lS.bx.get_top(), b.i + 1, lS.bx.get_bottom(),
border_color = color(na), bgcolor = srRZC),
box.new(na, na, na, na, bgcolor = color(na), border_color =
color(na)),
line.new(b.i[1], lS.bx.get_top(), b.i + 1, lS.bx.get_top(), color =
srRLC, width = srMR <= .5 ? 2 : 3),
false, false, false, false, lS.m))
//S.remove(0)

if srBS != 'None'
alert('Bearish breakout detected\n' + syminfo.ticker + ' price (' +
str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period)

else if lR.b and b.o[1] > lS.bx.get_bottom() and b.l[1] < lS.bx.get_top() and
b.c[1] > lS.bx.get_top() and not lS.r and b.i[1] != lS.bx.get_left()
label.new(b.i[1], b.l[1] * (1 - lS.m * .017), 'R', color = srRUC, style =
label.style_label_up , textcolor = srRTC, size = f_getSize(srRS), tooltip = 'Re-
test of Support Zone' + vST[1] )
lS.r := true //
lS.bx.set_right(b.i)
lS.ln.set_x2(b.i)

if srRS != 'None'
alert('Re-test of support zone detected\n' + syminfo.ticker + ' price
(' + str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period)

else if b.l[1] < lS.bx.get_top() and b.c[1] > lS.bx.get_bottom() and b.c >
lS.bx.get_bottom() and not lS.t and not lS.b and not lR.b and b.i[1] !=
lS.bx.get_left()
label.new(b.i[1], b.l[1] * (1 - lS.m * .017), 'T', color = srTUC, style =
label.style_label_up , textcolor = srTTC, size = f_getSize(srTS), tooltip = 'Test
of Support Zone' + vST[1] )
lS.t := true
lS.bx.set_right(b.i)
lS.ln.set_x2(b.i)

if srTS != 'None'
alert('Test of support zone detected\n' + syminfo.ticker + ' price (' +
str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period,
alert.freq_once_per_bar_close)

else if b.l < lS.bx.get_top() * (1 + lS.m * .17) and not lS.b //and
lS.bx.get_bottom() != lR.bx.get_bottom()
if b.l < lS.bx.get_top()
lS.bx.set_right(b.i)
lS.ln.set_x2(b.i)

if isLUS[1] and isHV[1] and srPS != 'None'


label.new(b.i[1], b.h[1] * (1 + lS.m * .017), '', color = srPDC, style =
label.style_label_down , textcolor = color.white, size = f_getSize(srPS), tooltip =
'Rejection of Higher Prices' + vST[1] )
alert('Rejection of higher prices detected\n' + syminfo.ticker + ' price ('
+ str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period)

if mnSH
if b.l < lS.bx.get_bottom() and b.c >= lS.bx.get_bottom() * (1 - lS.m * .17
* mnMR) and not lS.l and b.i == lS.bx.get_right()
if lS.lq.get_right() + srLN > b.i
lS.lq.set_right(b.i + 1)
lS.lq.set_bottom(math.max(math.min(b.l, lS.lq.get_bottom()),
lS.bx.get_bottom() * (1 - lS.m * .17 * mnMR)))
else
lS.lq.set_lefttop(b.i[1], lS.bx.get_bottom())
lS.lq.set_rightbottom(b.i + 1, math.max(b.l, lS.bx.get_bottom() *
(1 - lS.m * .17 * mnMR)))
lS.lq.set_bgcolor(mnSZC)

lS.l := true

else if b.l < lS.bx.get_bottom() and b.c >= lS.bx.get_bottom() * (1 - lS.m


* .17 * mnMR) and lS.l and b.i == lS.bx.get_right()
lS.lq.set_right(b.i + 1)
lS.lq.set_bottom(math.max(math.min(b.l, lS.lq.get_bottom()),
lS.bx.get_bottom() * (1 - lS.m * .17 * mnMR)))
else if lS.l and (b.c <= lS.bx.get_bottom() * (1 - lS.m * .17 * mnMR) or
b.c > lS.bx.get_top())
lS.l := false

if S.size() > 2 and srHST //and (lR.b or lS.b)// and lS.bx.get_bottom() !=


lR.bx.get_bottom()
lSt := S.get(1)

if lS.bx.get_bottom() != lSt.bx.get_bottom()

if srFBO and b.c[1] < lSt.bx.get_bottom() * (1 - lSt.m * .17) and not


lSt.b //and b.i[1] != lR.bx.get_left()
lSt.bx.set_right(b.i[1])
lSt.ln.set_x2(b.i[1])
lSt.b := true
lSt.r := false

label.new(b.i[1], b.h[1] * (1 + lSt.m * .017), 'B\n\n▼', color = srBDC,


style = label.style_label_down , textcolor = srBTC, size = f_getSize(srBS), tooltip
= 'Bearish Breakout' + vST[1] )

R.unshift(
SnR.new(
box.new(b.i[1], lSt.bx.get_top(), b.i + 1, lSt.bx.get_bottom(),
border_color = color(na), bgcolor = srRZC),
box.new(na, na, na, na, bgcolor = color(na), border_color =
color(na)),
line.new(b.i[1], lSt.bx.get_top(), b.i + 1, lSt.bx.get_top(),
color = srRLC, width = srMR <= .5 ? 2 : 3),
false, false, false, false, lSt.m))
//S.remove(1)

if srBS != 'None'
alert('Bearish breakout detected\n' + syminfo.ticker + ' price (' +
str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period)

else if b.c[1] < lSt.bx.get_bottom() and not lSt.b and not srFBO //and
b.i[1] != lR.bx.get_left()
lSt.bx.set_right(b.i[1])
lSt.ln.set_x2(b.i[1])
lSt.b := true
lSt.r := false

label.new(b.i[1], b.h[1] * (1 + lSt.m * .017), 'B\n\n▼', color = srBDC,


style = label.style_label_down , textcolor = srBTC, size = f_getSize(srBS), tooltip
= 'Bearish Breakout' + vST[1] )

R.unshift(
SnR.new(
box.new(b.i[1], lSt.bx.get_top(), b.i + 1, lSt.bx.get_bottom(),
border_color = color(na), bgcolor = srRZC),
box.new(na, na, na, na, bgcolor = color(na), border_color =
color(na)),
line.new(b.i[1], lSt.bx.get_top(), b.i + 1, lSt.bx.get_top(),
color = srRLC, width = srMR <= .5 ? 2 : 3),
false, false, false, false, lSt.m))
//S.remove(1)

if srBS != 'None'
alert('Bearish breakout detected\n' + syminfo.ticker + ' price (' +
str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period)

else if lRt.b and b.o[1] > lSt.bx.get_bottom() and b.l[1] <


lSt.bx.get_top() and b.c[1] > lSt.bx.get_top() and not lSt.r and b.i[1] !=
lSt.bx.get_left() //and lSt.bx.get_top() != lS.bx.get_top() //DGT
label.new(b.i[1], b.l[1] * (1 - lSt.m * .017), 'R', color = srRUC,
style = label.style_label_up , textcolor = srRTC, size = f_getSize(srRS), tooltip =
'Re-test of Support Zone' + vST[1] )
lSt.r := true
lSt.bx.set_right(b.i)
lSt.ln.set_x2(b.i)

if srRS != 'None'
alert('Re-test of support zone detected\n' + syminfo.ticker + '
price (' + str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period)

else if b.l[1] < lSt.bx.get_top() and b.c[1] > lSt.bx.get_bottom() and b.c
> lSt.bx.get_bottom() and not lSt.t and not lSt.b and not lRt.b and b.i[1] !=
lSt.bx.get_left()
label.new(b.i[1], b.l[1] * (1 - lSt.m * .017), 'T', color = srTUC,
style = label.style_label_up , textcolor = srTTC, size = f_getSize(srTS), tooltip =
'Test of Support Zone' + vST[1] )
lSt.t := true
lSt.bx.set_right(b.i)
lSt.ln.set_x2(b.i)

if srTS != 'None'
alert('Test of support zone detected\n' + syminfo.ticker + ' price
(' + str.tostring(b.c, format.mintick) + '), timeframe ' + timeframe.period,
alert.freq_once_per_bar_close)

else if b.l < lSt.bx.get_top() * (1 + lSt.m * .17) and not lSt.b


if b.l < lSt.bx.get_top()
lSt.bx.set_right(b.i)
lSt.ln.set_x2(b.i)

if mnSH
if b.l < lSt.bx.get_bottom() and b.c >= lSt.bx.get_bottom() * (1 -
lSt.m * .17 * mnMR) and not lSt.l and b.i == lSt.bx.get_right()
if lSt.lq.get_right() + srLN > b.i
lSt.lq.set_right(b.i + 1)
lSt.lq.set_bottom(math.max(math.min(b.l, lSt.lq.get_bottom()),
lSt.bx.get_bottom() * (1 - lSt.m * .17 * mnMR)))
else
lSt.lq.set_lefttop(b.i[1], lSt.bx.get_bottom())
lSt.lq.set_rightbottom(b.i + 1, math.max(b.l,
lSt.bx.get_bottom() * (1 - lSt.m * .17 * mnMR)))
lSt.lq.set_bgcolor(mnSZC)

lSt.l := true

else if b.l < lSt.bx.get_bottom() and b.c >= lSt.bx.get_bottom() * (1 -


lSt.m * .17 * mnMR) and lSt.l and b.i == lSt.bx.get_right()
lSt.lq.set_right(b.i + 1)
lSt.lq.set_bottom(math.max(math.min(b.l, lSt.lq.get_bottom()),
lSt.bx.get_bottom() * (1 - lSt.m * .17 * mnMR)))
else if lSt.l and (b.c <= lSt.bx.get_bottom() * (1 - lS.m * .17 * mnMR)
or b.c > lSt.bx.get_top())
lSt.l := false

//-----------------------------------------------------------------------------}

You might also like