0% found this document useful (0 votes)
12 views

Intersection value function

Best

Uploaded by

hamirjethava83
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 views

Intersection value function

Best

Uploaded by

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

_ = '

"Pinefest #1 October 21-28, 2023"

-----------------------------------------------------------------------------------
------------------------------------------------------
| █ CHALLENGE |
| |
| Create three functions that will return the exact value where two data series
intersect: |
| |
| • crossValue (source1, source2) |
| • crossoverValue (source1, source2) |
| • crossunderValue(source1, source2) |
| |
| When a cross occurs, the functions must return the intersection`s value. When no
cross occurs, they must return na. |
| |

-----------------------------------------------------------------------------------
------------------------------------------------------ '

//@version=5
indicator( title = 'Intersection Value Functions'
, max_boxes_count = 500
, max_lines_count = 500
, max_labels_count = 500
, overlay = true
)

//---------------------------------------------------------------------------------
------------------------------------}
//Challenge Functions
//---------------------------------------------------------------------------------
------------------------------------{
// getSlopes()
//
//@function Get the slope of the lines connecting source1/source2 to
source1[1]/source2[1]
//@param source1 (float) source value 1
//@param source2 (float) source value 2
//@returns Slopes of the lines
getSlopes(float source1, float source2) =>

//Get slopes
m1 = ta.change(source1)
m2 = ta.change(source2)

//Output
[m1 , m2]

// commonScalingFactor()
//
//@function Common scaling factor of the lines connecting source1/source2 to
source1[1]/source2[1]
//@param source1 (float) source value 1
//@param source2 (float) source value 2
//@param m1 (float) slope of the line originating from source1
//@param m2 (float) slope of the line originating from source2
//@returns Common scaling factor
commonScalingFactor(float source1, float source2, float m1, float m2) =>

//Output
(source1 - source2) / (m1 - m2)

// crossValue()
//
//@function Finds intersection value of 2 lines/values if any cross occurs - First
function of challenge -> crossValue(source1, source2)
//@param source1 (float) source value 1
//@param source2 (float) source value 2
//@returns Intersection value
method crossValue(float source1, float source2)=>
float insct = na

//Slope calculations, called on each bar


[m1, m2] = getSlopes(source1, source2)

//Test for cross


if ta.cross(source1, source2)

//Find common scaling factor


sf = commonScalingFactor(source1, source2, m1, m2)

//Find intersection value


insct := source1 - sf * m1

// crossoverValue()
//
//@function Finds intersection value of 2 lines/values if crossover occurs - Second
function of challenge -> crossoverValue(source1, source2)
//@param source1 (float) source value 1
//@param source2 (float) source value 2
//@returns Intersection value
method crossoverValue(float source1, float source2)=>
float insct = na

//Slope calculations, called on each bar


[m1, m2] = getSlopes(source1, source2)

//Test for cross


if ta.crossover(source1, source2)

//Find common scaling factor


sf = commonScalingFactor(source1, source2, m1, m2)
//Find intersection value
insct := source1 - sf * m1

// crossunderValue()
//
//@function Finds intersect of 2 lines/values if crossunder occurs - Third function
of challenge -> crossunderValue(source1, source2)
//@param source1 (float) source value 1
//@param source2 (float) source value 2
//@returns Intersection value
method crossunderValue(float source1, float source2) =>
float insct = na

//Slope calculations, called on each bar


[m1, m2] = getSlopes(source1, source2)

//Test for cross


if ta.crossunder(source1, source2)

//Find common scaling factor


sf = commonScalingFactor(source1, source2, m1, m2)

//Find intersection value


insct := source1 - sf * m1

//---------------------------------------------------------------------------------
------------------------------------}
//Usage - Code used to highlight the proposed functions usage.
//---------------------------------------------------------------------------------
------------------------------------{
//Settings
//-----------------------------------------------------------------------------{
//Sources selection
sourceA = input.string('SMA', 'Source A'
, options = ['SMA', 'EMA', 'WMA', 'Hull', 'External A']
, inline = 'sourceA')

lenA = input.int(9, '', minval = 1


, inline = 'sourceA')

externalA = input.source(close, 'External A')

sourceB = input.string('SMA', 'Source B'


, options = ['SMA', 'EMA', 'WMA', 'Hull', 'External B']
, inline = 'sourceB')

lenB = input.int(20, '', minval = 1


, inline = 'sourceB')
externalB = input.source(open, 'External B')

//Style
coCss = input.color(#2962ff, 'Crossover'
, inline = 'crossover')

coAreaCss = input.color(color.new(#2962ff, 90), ''


, inline = 'crossover')

cuCss = input.color(#ff5d00, 'Crossover'


, inline = 'crossunder')

cuAreaCss = input.color(color.new(#ff5d00, 90), ''


, inline = 'crossunder')

extend = input(true, 'Extend Intersections')

//SMA Intersection Matrix


showDash = input(true, 'Show Matrix'
, group = 'SMA Intersection Matrix')

minLen = input.int(10, 'SMA Length Range'


, minval = 1
, inline = 'lenrange'
, group = 'SMA Intersection Matrix')

maxLen = input.int(20, ''


, minval = 1
, inline = 'lenrange'
, group = 'SMA Intersection Matrix')

dashLoc = input.string('Top Right', 'Location'


, options = ['Top Right', 'Bottom Right', 'Bottom Left']
, group = 'SMA Intersection Matrix')

textSize = input.string('Small', 'Size'


, options = ['Tiny', 'Small', 'Normal']
, group = 'SMA Intersection Matrix')

//Magnifying Glass
magnify = input(true, 'Magnify'
, group = 'Magnifying Glass')

resolution = input.int(20, 'Resolution'


, minval = 2
, group = 'Magnifying Glass')
offset = input.int(10, 'Offset'
, minval = 2
, group = 'Magnifying Glass')

//----------------------------------------------------------------------------}
//Methods/Functions
//----------------------------------------------------------------------------{
//@function Return various supported moving averages outputs based on an input
string
//@param id (string) determine the function output, supported strings include
['SMA', 'EMA', 'WMA', 'Hull'], else an external value is returned
//@param len (simple int) moving average length if applicable
//@param external (float) external source
//@returns Chosen moving average output or "external" if "id" is not part of
supported options
method source(string id, simple int len, float external) =>
sma = ta.sma(close, len)
ema = ta.ema(close, len)
wma = ta.wma(close, len)
hma = ta.hma(close, len)

output = switch id
'SMA' => sma
'EMA' => ema
'WMA' => wma
'Hull' => hma
=> external

//@function Return the N * N intersection matrix from an array of values with size
N and the values in its previous instance
//@param array_series (array<float>) array of values, requires an array supporting
historical referencing
//@returns (matrix<float>) Intersection matrix showing intersection value between
all array entries
intersectionMatrix(array_series)=>
N = array_series.size()-1
ismt = matrix.new<float>(N+1, N+1)
sfmt = matrix.new<float>(N+1, N+1)

prev_array = array_series[1]

if not na(prev_array)
//Columns
for i = 0 to N
//Get source1 and previous source1 value
source1 = array_series.get(i)
prev1 = prev_array.get(i)

//source1 slope
m1 = source1 - prev1

//Rows
for j = i to N
//Na is column index = row index
if i == j
ismt.set(j, i, float(na))
else
//Get source2 and previous source2 value
source2 = array_series.get(j)
prev2 = prev_array.get(j)

//source2 slope
m2 = source2 - prev2

//Test for cross


if (source1 - source2) * (prev1 - prev2) < 0
//Find common scaling factor
sf = commonScalingFactor(source1, source2, m1, m2)

//Find intersection value


insct = source1 - sf * m1

//Set matrix intersection and scaling factor values


ismt.set(i, j, insct)
sfmt.set(i, j, 1 - sf)

//Output
[ismt, sfmt]

//@function Draw graphical elements on the chart highlighting crossing events and
intersection value/area
//@param intersection_val (float) Intersection value between source1 and source2
//@param scaling_factor (float) Common scaling factor between two crossing lines
//@param max (float) area top
//@param min (float) area bottom
//@param crossover (bool) true if the lines are crossing over each other
//@param css (color) color of the line/label text
//@param css_area (color) color of the box area
//@returns [line, label, box] drawing elements
draw(intersection_val, scaling_factor, max, min, crossover, css, css_area)=>
n = bar_index

//Intersection level
lvl = line.new(
chart.point.from_index(n-1, intersection_val)
, chart.point.from_index(n, intersection_val)
, color = css)

//Intersection value label and display 1 - scaling factor when hovering over
label
lbl = label.new(
chart.point.from_index(n, crossover ? min : max)
, color = color(na)
, textcolor = css
, text = str.tostring(math.round_to_mintick(intersection_val))
, style = crossover ? label.style_label_up : label.style_label_down
, size = size.small
, tooltip = str.tostring(1 - scaling_factor, '#.##'))

//Highlight intersection area


bx = box.new(
chart.point.from_index(n-1, max)
, chart.point.from_index(n, min)
, na
, bgcolor = css_area)

[lvl, lbl, bx]

//@function Display an higher resolution representation of intersecting lines


//@param source1 (float) source value 1
//@param source2 (float) source value 2
//@param css1 (color) color of source 1 line
//@param css2 (color) color of source 2 line
//@param intersec_css (color) color of intersection line
//@param area_css (color) color of box area
zoomIn(source1, source2, css1, css2, intersec_css, area_css)=>
var source1_l = line.new(na, na, na, na, color = css1)
var source2_l = line.new(na, na, na, na, color = css2)
var intersec_l = line.new(na, na, na, na)
var cross_area = box.new(na, na, na, na, chart.fg_color)

n = bar_index

//Find intersection value on crosses


intersection_val = source1.crossValue(source2)

//Draw new elements on crossing event


if not na(intersection_val)
//Get common scaling factor
sf = commonScalingFactor(source1, source2, source1 - source1[1], source2 -
source2[1])

//Slopes run
dx1 = int(resolution * (1 - sf))
dx2 = int(resolution * sf)

//Offset
start = int(resolution * (1 - sf)) + offset

//Coordinates
l1y1 = source1 - (source1 - source1[1]) * dx1
l1y2 = source1 + (source1 - source1[1]) * dx2

l2y1 = source2 - (source2 - source2[1]) * dx1


l2y2 = source2 + (source2 - source2[1]) * dx2
//Set new lines coordinates
source1_l.set_xy1(n - dx1 + start, l1y1)
source1_l.set_xy2(n + dx2 + start, l1y2)

source2_l.set_xy1(n - dx1 + start, l2y1)


source2_l.set_xy2(n + dx2 + start, l2y2)

intersec_l.set_xy1(n - dx1 + start, intersection_val)


intersec_l.set_xy2(n + dx2 + start, intersection_val)
intersec_l.set_color(intersec_css)

//Area
cross_area.set_lefttop(n - dx1 + start, math.max(l1y1, l1y2, l2y1, l2y2))
cross_area.set_rightbottom(n + dx2 + start, math.min(l1y1, l1y2, l2y1,
l2y2))
cross_area.set_bgcolor(area_css)
else
//Update coordinates
x1 = source1_l.get_x1()
x2 = source1_l.get_x2()

source1_l.set_x1(x1 + 1) , source1_l.set_x2(x2 + 1)
source2_l.set_x1(x1 + 1) , source2_l.set_x2(x2 + 1)
intersec_l.set_x1(x1 + 1) , intersec_l.set_x2(x2 + 1)
cross_area.set_left(x1 + 1), cross_area.set_right(x2 + 1)

//----------------------------------------------------------------------------}
//Highlight crosses and intersection value
//----------------------------------------------------------------------------{
//Intersections drawing elements
var line intersection_lvl = na
var label intersection_lbl = na
var box intersection_box = na

n = bar_index
source1 = sourceA.source(lenA, externalA)
source2 = sourceB.source(lenB, externalB)

//Find intersection value on crosses


intersection_val = source1.crossValue(source2)

var l1 = line.new(na,na,na,na)
var l2 = line.new(na,na,na,na)
var l3 = line.new(na,na,na,na)

//Highlight intersection information


if not na(intersection_val)

//Get common scaling factor


sf = commonScalingFactor(source1, source2, source1 - source1[1], source2 -
source2[1])

//Draw elements
crossover = source1 > source2
max = math.max(source1, source2, source1[1], source2[1])
min = math.min(source1, source2, source1[1], source2[1])

[lvl_, lbl_, bx_] = draw(intersection_val, sf, max, min


, crossover
, crossover ? coCss : cuCss
, crossover ? coAreaCss : cuAreaCss)

intersection_lvl := lvl_
intersection_lbl := lbl_
intersection_box := bx_

else
//Extend
if extend
intersection_lvl.set_x2(n)
intersection_lbl.set_x(int(math.avg(n, intersection_lvl.get_x1())))
intersection_box.set_right(n)

//Zoom
if magnify
zoomIn(source1, source2, #089981, #f23645
, source1 > source2 ? coCss : cuCss
, source1 > source2 ? coAreaCss : cuAreaCss)

//-----------------------------------------------------------------------------}
//Highlight SMA intersection matrix
//-----------------------------------------------------------------------------{
var table_position = dashLoc == 'Bottom Left' ? position.bottom_left
: dashLoc == 'Top Right' ? position.top_right
: position.bottom_right

var table_size = textSize == 'Tiny' ? size.tiny


: textSize == 'Small' ? size.small
: size.normal

//Declare array of sma values


sma_array = array.new<float>(0)

csum = ta.cum(close)

//Calculate SMA for periods from min_per to max_per


for i = minLen to maxLen
ma = (csum - csum[i]) / i
sma_array.push(ma)
//Get matrices
[ismt, sfmt] = intersectionMatrix(sma_array)

//Set SMA intersection matrix


if barstate.islast and showDash
cols = ismt.columns()
rows = ismt.rows()

//Table
tb = table.new(table_position, cols+2, rows+2
, bgcolor = #1e222d
, border_color = #373a46
, border_width = 1
, frame_color = #373a46
, frame_width = 1)

for i = 0 to rows-1
//SMA periods
tb.cell(0, i+1, str.tostring(minLen + i)
, text_color = color.white
, text_size = table_size)

tb.cell(i+1, 0, str.tostring(minLen + i)
, text_color = color.white
, text_size = table_size)

for j = 0 to cols-1
//Set intersection value
if not na(ismt.get(i, j))
tb.cell(i+1, j+1, str.tostring(math.round_to_mintick(ismt.get(i,
j)))
, text_color = color.white
, text_size = table_size
, tooltip = str.tostring(sfmt.get(i, j), '#.##'))

//Dashboard title
tb.cell(0, rows, 'SMA Intersection Matrix'
, text_color = color.white
, text_size = table_size)
tb.merge_cells(0, rows, cols, rows)

//----------------------------------------------------------------------------}
//Plots
//----------------------------------------------------------------------------{
plot(source1, 'Source A', #089981)
plot(source2, 'Source B', #f23645)

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

You might also like