D-Shape Breakout Signals [LuxAlgo]

LuxAlgo · study · 327 行 · 点赞 3,954 · TradingView 原页

本页源码来自 TradingView 公开发布的开源脚本,版权归原作者所有, 请遵循其原始许可(Pine 脚本常见 CC BY-NC-SA / MPL-2.0 / MIT)。 本项目仅用于研究检索与许可范围内的移植。

Pine Script

// 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)
 )
 
//---------------------------------------------------------------------------------------------------------------------}

← 返回列表