// This source code is subject to the terms of the Mozilla Public License 2.
0 at
[Link]
// © pikusov
//
// Diagonal Supports and Resistances
//
// Classic diagonal support and resistance based on pivot points.
// As a result, they form triangles, wedges, channels and other patterns.
// Realtime update up to 1 second chart.
//
// Input parameters:
// History Bars Back: Number of bars back to find high and low points
// Please note that History Bars Back more than 300 may cause errors
// Resolution: The power of high and low points to take into drawing
//
// You can enable alerts for crossing supports and resistances in the Alerts menu
// [Link]
//
//@version=5
var int max_bars_back = 5000
indicator('2 - Trendline Diagonal', overlay=true, max_bars_back=max_bars_back)
var int history_bars = input(title='History bars back', defval=300)
col_sup = [Link]([Link], 50)
style_sup = line.style_solid
col_res = [Link]([Link], 50)
style_res = line.style_solid
// Функция вычисляет цену в точке t3 для линии,
// заданной первыми четырьмя координатами (t1, p1, t2, p2)
price_at(t1, p1, t2, p2, t3) =>
p1 + (p2 - p1) * (t3 - t1) / (t2 - t1)
// Alerts
if 1 == 1
alert('Test')
// округление
round_to_tick(x) =>
mult = 1 / [Link]
value = [Link](x * mult) / mult
value
// Тут храним линии для удаления при появлении нового бара
var line[] supports = array.new_line()
var line[] resistances = array.new_line()
var label[] labels = array.new_label()
fire_alert_sup = false
fire_alert_res = false
fire_alert_sup := false
fire_alert_res := false
// Удаляем прошлые линии и заодно вызываем алерты
line temp_line = na
if [Link](supports) > 0
for i = [Link](supports) - 1 to 0 by 1
temp_line := [Link](supports, i)
if low[1] > line.get_price(temp_line, bar_index - 1) and close <
line.get_price(temp_line, bar_index)
fire_alert_sup := true
fire_alert_sup
[Link](temp_line)
[Link](supports, i)
if [Link](resistances) > 0
for i = [Link](resistances) - 1 to 0 by 1
temp_line := [Link](resistances, i)
if high[1] < line.get_price(temp_line, bar_index - 1) and close >
line.get_price(temp_line, bar_index)
fire_alert_res := true
fire_alert_res
[Link](temp_line)
[Link](resistances, i)
label temp_label = na
if [Link](labels) > 0
for i = [Link](labels) - 1 to 0 by 1
temp_label := [Link](labels, i)
[Link](temp_label)
[Link](labels, i)
alertcondition(fire_alert_sup, 'Diagonal Support Alert', 'Diagonal support crossed
down')
alertcondition(fire_alert_res, 'Diagonal Resistance Alert', 'Diagonal resistance
crossed up')
// Определяем экстремумы
min_values = low
max_values = high
x1 = input(title='Resolution (bars)', defval=6)
x2 = [Link](x1 / 2)
int minimums = 0
minimums := [Link](min_values, x1) == -x2 ? x2 : minimums[1] + 1
int maximums = 0
maximums := [Link](max_values, x1) == -x2 ? x2 : maximums[1] + 1
int minimum1 = 0
int minimum2 = 0
int maximum1 = 0
int maximum2 = 0
int medium = 0
// Поддержка
if [Link]
//[Link](bar_index, close , style=label.style_labeldown,
text=[Link], color=[Link]([Link], 90))
line last_line = na
label last_label = na
for k1 = 0 to 50 by 1
if minimum1 >= history_bars
break
minimum1 += minimums[minimum1]
minimum2 := minimum1 * 2
for k2 = 0 to 50 by 1
if minimum2 >= minimum1 * 8 or minimum2 >= history_bars
break
minimum2 += minimums[minimum2]
if minimum1 >= history_bars or minimum2 >= history_bars
break
bar1 = bar_index - minimum1
bar2 = bar_index - minimum2
price1 = low[minimum1]
price2 = low[minimum2]
current_price = price_at(bar2, price2, bar1, price1, bar_index)
// Если поддержка проходит ниже текущей цены
if current_price < high[1]
// проверяем пересечения
crossed = 0
medium := 0
for k3 = 0 to 50 by 1
if medium >= minimum2
break
medium += minimums[medium]
if medium >= minimum2
break
if price_at(bar2, price2, bar1, price1, bar_index - medium) >
[Link](open[medium], close[medium])
crossed := 1
break
// если нет пересечений
if crossed == 0 // and overtilt == 0
// сравниваем с прошлой созданной линией
if not na(last_line)
last_price = price_at(line.get_x1(last_line),
line.get_y1(last_line), line.get_x2(last_line), line.get_y2(last_line), bar_index)
if bar1 == line.get_x2(last_line)
if current_price > last_price
line.set_xy1(last_line, bar2, price2)
line.set_xy2(last_line, bar1, price1)
line.set_color(last_line, col_sup)
label.set_xy(last_label, bar_index, current_price)
label.set_text(last_label,
[Link](round_to_tick(current_price)))
true
else
last_line := [Link](bar2, price2, bar1, price1,
extend=[Link], color=col_sup, style=style_sup)
last_label := [Link](bar_index, current_price,
color=col_sup, style=label.style_label_upper_left,
text=[Link](round_to_tick(current_price)), size = [Link], textcolor =
[Link])
[Link](labels, last_label)
[Link](supports, last_line)
true
else
// добавляем линию
last_line := [Link](bar2, price2, bar1, price1,
extend=[Link], color=col_sup, style=style_sup)
last_label := [Link](bar_index, current_price,
color=col_sup, style=label.style_label_upper_left,
text=[Link](round_to_tick(current_price)), size = [Link], textcolor =
[Link])
[Link](labels, last_label)
[Link](supports, last_line)
true
last_line := na
last_label := na
for k1 = 0 to 100 by 1
if maximum1 >= history_bars
break
maximum1 += maximums[maximum1]
maximum2 := maximum1 * 2
for k2 = 0 to 50 by 1
if maximum2 >= maximum1 * 8 or maximum2 >= history_bars
break
maximum2 += maximums[maximum2]
if maximum1 >= history_bars or maximum2 >= history_bars
break
bar1 = bar_index - maximum1
bar2 = bar_index - maximum2
price1 = high[maximum1]
price2 = high[maximum2]
current_price = price_at(bar2, price2, bar1, price1, bar_index)
// Если сопротивоение проходит выше текущей цены
if current_price > low[1]
// проверяем пересечения
crossed = 0
medium := 0
for k3 = 0 to 100 by 1
if medium >= maximum2
break
medium += maximums[medium]
if medium >= maximum2
break
if price_at(bar2, price2, bar1, price1, bar_index - medium) <
[Link](open[medium], close[medium])
crossed := 1
break
// если нет пересечений
if crossed == 0 // and overtilt == 0
// сравниваем с прошлой созданной линией
if not na(last_line)
last_price = price_at(line.get_x1(last_line),
line.get_y1(last_line), line.get_x2(last_line), line.get_y2(last_line), bar_index)
if bar1 == line.get_x2(last_line)
if current_price < last_price
line.set_xy1(last_line, bar2, price2)
line.set_xy2(last_line, bar1, price1)
line.set_color(last_line, col_res)
label.set_xy(last_label, bar_index, current_price)
label.set_text(last_label,
[Link](round_to_tick(current_price)))
true
else
last_line := [Link](bar2, price2, bar1, price1,
extend=[Link], color=col_res, style=style_res)
last_label := [Link](bar_index, current_price,
color=col_res, style=label.style_label_lower_left,
text=[Link](round_to_tick(current_price)), size = [Link], textcolor =
[Link])
[Link](labels, last_label)
[Link](resistances, last_line)
true
else
// добавляем линию
last_line := [Link](bar2, price2, bar1, price1,
extend=[Link], color=col_res, style=style_res)
last_label := [Link](bar_index, current_price,
color=col_res, style=label.style_label_lower_left,
text=[Link](round_to_tick(current_price)), size = [Link], textcolor =
[Link])
[Link](labels, last_label)
[Link](resistances, last_line)
true