本页源码来自 TradingView 公开发布的开源脚本,版权归原作者所有, 请遵循其原始许可(Pine 脚本常见 CC BY-NC-SA / MPL-2.0 / MIT)。 本项目仅用于研究检索与许可范围内的移植。
// This work is licensed under a Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) https://creativecommons.org/licenses/by-nc-sa/4.0/
// © LuxAlgo
//@version=5
indicator('D-Shape Breakout Signals [LuxAlgo]', shorttitle='LuxAlgo - D-Shape Breakout Signals', max_labels_count=500, max_lines_count=200, max_polylines_count=100, max_bars_back=5000, overlay=true)
//---------------------------------------------------------------------------------------------------------------------}
// Settings
//---------------------------------------------------------------------------------------------------------------------{
left = input.int ( 50, 'Swing Length' , minval= 1 )
binSize = input.int ( 1, 'Minumum Patterns' , minval= 1, maxval= 100 , group='D-Patterns'
, tooltip ='Minimal Amount Of Visible D-Patterns\n (Active Patterns won\'t be deleted)') -1
cWidth = input.int ( 100, 'D-Width' , minval=50, maxval= 1500 , group='D-Patterns'
, tooltip ='% Distance Swings' ) / 50
swings = input.string('Swing High/Low', 'Included Swings'
, options =[ 'Swing High', 'Swing Low', 'Swing High/Low' ])
styleD = input.string('Arc', 'Style Historical Patterns', options=['Arc', 'Midline', 'Both' ])
size = str.lower(input.string( 'Small', 'Label Size' , group='Style'
, options =[ 'Tiny', 'Small', 'Normal','Large' ]) )
cBull = input.color (#089981, 'Bull ' , group='Style' )
cBear = input.color (#f23645, 'Bear' , group='Style' )
cNeut = input.color (#085def, 'Neutral' , group='Style' )
origine = input.bool ( true, 'Connecting Swing Level' , group='Style' )
iFill = input.bool ( true, 'Color Fill' , group='Style' )
//---------------------------------------------------------------------------------------------------------------------}
//LuxAlgo Defined Types
//---------------------------------------------------------------------------------------------------------------------{
type D
bool bear
array<chart.point>cp1
array<chart.point>cp2
array<chart.point>cp3
polyline poly1
polyline poly2
line mid
line orig
bool act
= true
//---------------------------------------------------------------------------------------------------------------------}
//Constants and general variables
//---------------------------------------------------------------------------------------------------------------------{
n = bar_index
INV = color(na)
pi = math.pi
pi2 = pi / 2
//---------------------------------------------------------------------------------------------------------------------}
//Variables
//---------------------------------------------------------------------------------------------------------------------{
breakOut = false
var float tsl = close
var float tslU = na
var float tslD = na
var int trend = 0
var array<D>aD = array.new< D >()
//---------------------------------------------------------------------------------------------------------------------}
//Methods
//---------------------------------------------------------------------------------------------------------------------{
method set_Historical_D(D D, color col) =>
D.poly1.delete(), D.poly2.delete(), D.act := false
switch styleD
'Arc' =>
if D.bear
D.cp1.pop()
D.cp2.shift()
else
D.cp1.shift(), D.cp1.pop()
D.cp2.shift(), D.cp2.pop()
D.poly1 := polyline.new(D.cp1, closed=false, line_color=color.new(col, 65))
D.poly2 := polyline.new(D.cp2, closed=false, line_color=color.new(col, 65))
if origine
D.orig .set_color( color.new(col, 35))
'Midline' =>
D.mid .set_color( color.new(col, 65))
if origine
D.orig .set_color( color.new(col, 35))
=>
D.cp1.unshift (D.cp2.last() )
D.poly1 := polyline.new(D.cp1, closed=false, line_color=color.new(col, 65))
D.poly2 := polyline.new(D.cp2, closed=false, line_color=color.new(col, 65))
D.mid .set_color( color.new(col, 65))
if origine
D.orig .set_color( color.new(col, 35))
//---------------------------------------------------------------------------------------------------------------------}
//Exec
//---------------------------------------------------------------------------------------------------------------------{
if barstate.isfirst
for i = 0 to binSize
aD.push(
D.new(
na
, array.new<chart.point>()
, array.new<chart.point>()
, array.new<chart.point>()
, polyline.new(na)
, polyline.new(na)
, line(na)
, line(na)
, false)
)
ph = ta.pivothigh(left , 1 )
vwPh_bix = ta.valuewhen(not na(ph), n-1, 0)
vwPh_prc = ta.valuewhen(not na(ph), ph , 0)
pl = ta.pivotlow (left , 1 )
vwPl_bix = ta.valuewhen(not na(pl), n-1, 0)
vwPl_prc = ta.valuewhen(not na(pl), pl , 0)
swingHL = swings != 'Swing Low'
swingLH = swings != 'Swing High'
//swing H -> L
if swingHL and not na(pl) and na(ph) and pl < vwPh_prc
points1= array.new<chart.point>()
points2= array.new<chart.point>()
points3= array.new<chart.point>()
width = math.min(998, (n-1 - vwPh_bix) * cWidth) //#bars
height = vwPh_prc - pl //#price
lastY = 0.,lastY2 = 0.,lastX = n-2
avg = math.avg(vwPh_prc, pl)
h2 = height / 2
w2 = width / 2
y = avg - ((h2 * math.sin(pi - (pi2 / w2*width/2))))
y2 = avg + ((h2 * math.sin(pi - (pi2 / w2*width/2))))
x = n -1
points1.push (chart.point.from_index(x , y ))
points2.unshift(chart.point.from_index(x , y2))
for i = width / 2 to 0
//Make Quarter Circle (quadrant 1 clockwise)
x := math.floor(n-1 - ((w2 * math.cos(pi + (pi2 / w2*i)))))
y := avg - (h2 * math.sin(pi + (pi2 / w2*i)))
if x != lastX
and x >= n-1
diff = x - lastX
if diff > 1
for j = 1 to diff -1
x_ = lastX + j
y_ = lastY - ((lastY - y ) / diff * j)
points1.push (chart.point.from_index(x_, y_ ))
points2.unshift(chart.point.from_index(x_, avg - (y_ - avg)))
points1 .push (chart.point.from_index(x , y ))
points2 .unshift(chart.point.from_index(x , avg - (y - avg)))
lastY := y
lastX := x
Dnew = D.new()
points1.push (chart.point.from_index(x , avg))
points1.push (chart.point.from_index(n-1, avg))
Dnew.cp1 := points1
Dnew.poly1 := polyline.new(points1, closed=true, line_color=cBull)
points2.unshift(chart.point.from_index(x , avg))
points2.unshift(chart.point.from_index(n-1, avg))
Dnew.cp2 := points2
Dnew.poly2 := polyline.new(points2, closed=true, line_color=cBull)
Dnew.mid := line.new(n-1, math.avg(vwPh_prc, pl), n-1+w2, math.avg(vwPh_prc, pl), color=INV)
points3 := points1.copy()
points3.concat(points2)
Dnew.cp3 := points3
Dnew.bear := false
if origine
Dnew.orig := line.new(vwPh_bix, vwPh_prc, n-1, vwPh_prc, color=cBull, style=line.style_dotted)
aD.unshift(Dnew)
//Swing L -> H
if swingLH and not na(ph) and na(pl) and ph > vwPl_prc
points1= array.new<chart.point>()
points2= array.new<chart.point>()
points3= array.new<chart.point>()
width = math.max(-998, (vwPl_bix - n-1) * cWidth) //#bars
height = ph - vwPl_prc //#price
lastY = 0.,lastY2 = 0.,lastX = n-2
avg = math.avg(vwPl_prc, ph)
h2 = height / 2
w2 = width / 2
y = avg - ((h2 * math.sin(pi + (pi2 / w2*width/2))))
y2 = avg + ((h2 * math.sin(pi + (pi2 / w2*width/2))))
x = n -1
points1.push (chart.point.from_index(x , y ))
points2.unshift(chart.point.from_index(x , avg + (avg - y )))
for i = width / 2 to 0
//Make Quarter Circle (quadrant 1 clockwise)
d = (h2 * math.sin(pi + (pi2 / w2*i)))
x := math.floor(n-1 + ((w2 * math.cos(pi + (pi2 / w2*i)))))
y := avg - (h2 * math.sin(pi + (pi2 / w2*i)))
if x != lastX
and x >= n-1
diff = x - lastX
if diff > 1
for j = 1 to diff -1
x_ = lastX + j
y_ = lastY - ((lastY - y ) / diff * j)
points1.push (chart.point.from_index(x_, y_ ))
points2.unshift(chart.point.from_index(x_, avg + (avg - y_)))
points1 .push (chart.point.from_index(x , y ))
points2 .unshift(chart.point.from_index(x , avg + (avg - y )))
lastY := y
lastX := x
Dnew = D.new()
points1.push (chart.point.from_index(x , avg))
points1.push (chart.point.from_index(n-1, avg))
Dnew.cp1 := points1
Dnew.poly1 := polyline.new(points1, closed=true, line_color=cBear)
points2.unshift(chart.point.from_index(x , avg))
points2.unshift(chart.point.from_index(n-1, avg))
Dnew.cp2 := points2
Dnew.poly2 := polyline.new(points2, closed=true, line_color=cBear)
Dnew.mid := line.new(n-1, math.avg(vwPl_prc, ph), n-1-w2, math.avg(vwPl_prc, ph), color=INV)
points3 := points1.copy()
points3.concat(points2)
Dnew.cp3 := points3
Dnew.bear := true
if origine
Dnew.orig := line.new(vwPl_bix, vwPl_prc, n-1, vwPl_prc, color=cBear, style=line.style_dotted)
aD.unshift(Dnew)
aDsz = aD.size()
if aDsz > 0
for i = aDsz -1 to 0
get = aD.get(i)
if get.act and get.cp3.size() > 0
if n > get.mid.get_x2()
label.new(n, high, color=INV, text='●', textcolor=color.blue, style=label.style_label_down, size=size)
get.set_Historical_D(cNeut)
else
//get Upper Half of Arc
for j = 0 to math.round(get.cp3.size() /2) -1
point = get.cp3.get(j)
if point.index == n
//Add Arc- & Midline price to pointsU when close is lower
price = point.price
l_prc = get.mid.get_y2()
//Breakout Arc Top
if close > price
label.new(n, high, color=INV, text='●', textcolor=cBull, style=label.style_label_down, size=size)
get.set_Historical_D(cBull)
trend := 1
breakOut := true
tslD := trend[1] == -1 ? l_prc : math.max(tslD, l_prc)
break
//get Lower Half of Arc
for j = math.round(get.cp3.size() /2) to get.cp3.size() -1
point = get.cp3.get(j)
if point.index == n
//Add Arc- & Midline price to pointsD when close is higher
price = point.price
l_prc = get.mid.get_y2()
//Breakout Arc Bottom
if close < price
label.new(n, low, color=INV, text='●', textcolor=cBear, style=label.style_label_up, size=size)
get.set_Historical_D(cBear)
trend := -1
breakOut := true
tslU := trend[1] == 1 ? l_prc : math.min(tslU, l_prc)
break
//Clean IF aDsz > binSize AND not active
if aDsz > binSize
diff = aDsz - binSize
for i = aD.size() -1 to binSize
get = aD.get(i)
if aD.size() -1 > binSize and not get.act
removedD = aD.remove(i)
removedD.poly1.delete()
removedD.poly2.delete()
removedD.mid .delete()
removedD.orig .delete()
diff -= 1
if aD.size() -1 <= binSize
break
if breakOut
tsl := trend == 1 ? tslD : trend == -1 ? tslU : close < tsl ? -1 : 1
//---------------------------------------------------------------------------------------------------------------------}
//Plot
//---------------------------------------------------------------------------------------------------------------------{
t = plot(tsl
, color=ta.change(trend) != 0 ? color(na) : trend < 1 ? cBear : cBull
, style=plot.style_linebr, display=display.all - display.status_line)
c = plot(close, color=color(na), display=display.none)
fill(c, t
, not iFill ? na : trend == 1 ? tsl : close
, not iFill ? na : trend == 1 ? close : tsl
, not iFill ? na : trend == 1 ? color.new(cBull, 80)
: color(na)
, not iFill ? na : trend == 1 ? color(na)
: color.new(cBear, 80)
)
//---------------------------------------------------------------------------------------------------------------------}