Auto Chart Patterns

Category: Indicators By: Iván González Created: July 23, 2026, 4:02 PM
July 23, 2026, 4:02 PM
Indicators
0 Comments

1. Introduction

Channels, wedges and triangles are the bread and butter of classical chart reading, but spotting them by hand is slow and subjective: two traders draw two different trend lines on the same swing. This indicator, adapted to ProBuilder from the “Auto Chart Patterns [Trendoscope]” pinescript, does the drawing for you and, more importantly, does it by a fixed rule.

It builds a recursive zigzag – the same engine used in the ABC on Recursive Zigzag indicator – and on top of it reads every group of five consecutive pivots as a candidate pattern. Two trend lines are fitted, validated against the price, and the result is classified into one of thirteen pattern types across three families: channels, wedges and triangles.

 

2. How It Works

The recursive zigzag. Level 0 marks a pivot whenever the current bar holds the highest high or lowest low of the last zzLen bars. Each higher level is distilled from the one below: a pivot survives only if it is an extreme within its own series. This lets the same pattern be found at several scales at once.

Two trend lines from five pivots. At each level the last five pivots are taken. The odd-indexed points (1-3-5) form one trend line, the even-indexed points (2-4) the other. One line rides the highs, the other the lows.

Validation – a good trend line envelops price. This is the heart of the indicator and it is deliberately counter-intuitive. A line is accepted only if, walking every bar of the pattern:

  • no candle body closes on the wrong side of it (the line was never decisively broken), and
  • it touches price on fewer than 20% of the bars.

That second rule is the key: a proper support or resistance line sits outside the price and grazes it only at the pivots. A line that cuts through the middle of the candles, touching them constantly, is not a clean boundary and is rejected. For each side three point combinations are tried and the best valid one is kept.

Classification. With both lines fixed, the indicator measures the direction of each line (rising, falling or flat, governed by flatRatio) and whether the lines converge, diverge or stay parallel. That produces the pattern type:

  • Channels – the two lines are parallel: Ascending, Descending or Ranging.
  • Wedges – both lines move the same way while converging or diverging: Rising/Falling Wedge, in Expanding or Contracting form.
  • Triangles – the lines move in different directions or one is flat: Ascending/Descending Triangle (Expanding or Contracting), Converging Triangle, Diverging Triangle.

3. Reading the Indicator

  • Two solid trend lines: the boundaries of the pattern. Grey for channels, orange for wedges, blue for triangles.
  • Dotted internal line: the zigzag of the five pivots that define the pattern.
  • Numbers 1 to 5: the pivots, in order.
  • Label: the pattern name, drawn at the last pivot.

Only non-overlapping patterns are kept, and the most recent ones, so the chart stays readable instead of piling several near-identical figures on top of each other.

 

4. Trading Applications

  • A rule-based second opinion. Instead of arguing with yourself about where the trend line goes, you get one drawn by a fixed validation rule. If the indicator will not draw a wedge there, the wedge probably was not clean.
  • Breakout anticipation. Contracting patterns (converging triangles, contracting wedges) point to an energy build-up; the two lines show exactly where a break would occur.
  • Context by family. Channels describe orderly trends, wedges often precede reversals, and triangles mark consolidation. The colour coding lets you read the market’s current mode at a glance.
  • Screening. A companion ProScreener (built from the same engine) filters an entire universe for symbols that have just formed a pattern of the family you care about.

5. Parameters

  • zzLen (default 8): lookback for the base zigzag. Larger values give fewer, bigger patterns.
  • mxLevel (default 2): how many recursive levels to scan. The useful ceiling is usually 1-2.
  • mnLevel (default 0): skip the smallest levels by raising this.
  • mxPivots (default 120): how many base pivots feed the scan; the main performance lever.
  • errRatio (default 0.2): the trend-line validation threshold (fraction of bars the line may touch). Lower is stricter.
  • flatRatio (default 0.2): how much slope a line may have before it still counts as flat.
  • useBR / brLimit (1 / 0.382): require the legs between pivots to be proportionate.
  • allowChannels / allowWedges / allowTriangles, allowRising / allowFalling / allowFlat, allowExpanding / allowContracting / allowParallel: filter which of the 13 types are shown, by family, direction and formation.
  • mxPat (default 8): how many patterns stay on the chart at once.
  • shZig / shPivL / shPatL: toggle the internal zigzag, the pivot numbers and the name label.

6. A Note on Repainting

The underlying zigzag does not wait for confirmation: a pivot is marked as soon as the current bar holds the extreme of its window, so the most recent pivot can still move while its bar is forming. This is by design in the original and it is preserved here. In practice it means the newest pattern on the chart is provisional until the swing that defines it is complete. Patterns further back do not change.

 

7. Auto Chart Patterns Code

//-----------------------------------------------------------//
//PRC_Auto Chart Patterns (by Trendoscope)
//version = 0
//23.07.26
//Ivan Gonzalez @ www.prorealcode.com
//Sharing ProRealTime knowledge
//-----------------------------------------------------------//
// Detecta automaticamente patrones chartistas de lineas de
// tendencia (canales, cunas y triangulos, 13 tipos) sobre un
// zigzag recursivo multinivel. En cada nivel toma los ultimos
// 5 pivotes, ajusta dos lineas de tendencia (pares 1-3-5 e
// impares 2-4), valida que envuelven el precio y clasifica el
// patron por la direccion y convergencia de las dos lineas.
//-----------------------------------------------------------//
defparam drawonlastbaronly = true
//-----Parametros (editables)--------------------------------//
zzLen = 8             //Longitud del zigzag de nivel 0
mxLevel = 2           //Nivel maximo de zigzag recursivo (0 = solo base)
mnLevel = 0           //Nivel minimo a escanear
mxPivots = 120        //Pivotes de nivel 0 usados en el escaneo

errRatio = 0.2        //Umbral de validacion de linea (toque < 20% de barras)
flatRatio = 0.2       //Umbral para considerar una linea plana
useBR = 1             //1 = verificar proporcion de barras entre pivotes
brLimit = 0.382       //Limite de proporcion de barras (r en [brLimit, 1/brLimit])
avoidOv = 1           //1 = evitar patrones solapados

//-----Grupos de patrones (1 = permitido)--------------------//
allowChannels = 1     //Canales (lineas paralelas)
allowWedges = 1       //Cunas (lineas en misma direccion)
allowTriangles = 1    //Triangulos (lineas en distinta direccion)

allowRising = 1       //Alcistas
allowFalling = 1      //Bajistas
allowFlat = 1         //Planos / bidireccionales

allowExpanding = 1    //Expansivos (lineas divergen)
allowContracting = 1  //Contractivos (lineas convergen)
allowParallel = 1     //Paralelos (canales)

//-----Display-----------------------------------------------//
mxPat = 8             //Patrones activos simultaneos (FIFO)
shZig = 1             //1 = dibujar el zigzag del patron
shPivL = 1            //1 = etiquetar los pivotes 1..5
shPatL = 1            //1 = etiquetar el nombre del patron
zzr = 100             //color del zigzag (RGB)
zzg = 100
zzb = 255
//-----------------------------------------------------------//
//-----allowed[1..13]: cruce grupo x direccion x formacion---//
// 1 AscCh 2 DescCh 3 RangeCh 4 RWExp 5 FWExp 6 DivTri
// 7 AscTriExp 8 DescTriExp 9 RWCon 10 FWCon 11 ConvTri
// 12 DescTriCon 13 AscTriCon
$allowed[1] = allowChannels * allowRising * allowParallel
$allowed[2] = allowChannels * allowFalling * allowParallel
$allowed[3] = allowChannels * allowFlat * allowParallel
$allowed[4] = allowWedges * allowRising * allowExpanding
$allowed[5] = allowWedges * allowFalling * allowExpanding
$allowed[6] = allowTriangles * allowFlat * allowExpanding
$allowed[7] = allowTriangles * allowRising * allowExpanding
$allowed[8] = allowTriangles * allowFalling * allowExpanding
$allowed[9] = allowWedges * allowRising * allowContracting
$allowed[10] = allowWedges * allowFalling * allowContracting
$allowed[11] = allowTriangles * allowFlat * allowContracting
$allowed[12] = allowTriangles * allowFalling * allowContracting
$allowed[13] = allowTriangles * allowRising * allowContracting
//-----------------------------------------------------------//
//-----OHLC indexado por barindex (como el ohlcArray original)//
// inspect lee estos arrays, NO el operador historico open[n]:
// open[barindex-bi] con offset variable en un bucle no es fiable
// y devolvia 0 -> la linea inferior se invalidaba siempre.
$barO[barindex] = open
$barH[barindex] = high
$barL[barindex] = low
$barC[barindex] = close
//-----------------------------------------------------------//
//-----NIVEL 0: deteccion de pivotes (ZigzagLite)------------//
newPivot = 0
IF barindex >= zzLen THEN
   hb = highestbars[zzLen](high)
   lb = lowestbars[zzLen](low)
   
   IF hb = 0 AND lb <> 0 THEN
      pvDir = 1
      pvVal = high
   ELSIF lb = 0 AND hb <> 0 THEN
      pvDir = -1
      pvVal = low
   ELSIF hb = 0 AND lb = 0 THEN
      pvDir = prevDir
      IF pvDir = 1 THEN
         pvVal = high
      ELSE
         pvVal = low
      ENDIF
   ELSE
      pvDir = 0
      pvVal = 0
   ENDIF
   
   IF pvDir <> 0 THEN
      IF pvDir = 1 THEN
         isHi = 1
      ELSE
         isHi = 0
      ENDIF
      
      IF npv = 0 THEN
         $zI[0] = barindex
         $zP[0] = pvVal
         $zH[0] = isHi
         npv = 1
         newPivot = 1
      ELSE
         lastH = $zH[npv-1]
         IF lastH = isHi THEN
            lastP = $zP[npv-1]
            IF isHi = 1 THEN
               IF pvVal > lastP THEN
                  $zI[npv-1] = barindex
                  $zP[npv-1] = pvVal
                  newPivot = 1
               ENDIF
            ELSE
               IF pvVal < lastP THEN
                  $zI[npv-1] = barindex
                  $zP[npv-1] = pvVal
                  newPivot = 1
               ENDIF
            ENDIF
         ELSE
            $zI[npv] = barindex
            $zP[npv] = pvVal
            $zH[npv] = isHi
            npv = npv + 1
            newPivot = 1
         ENDIF
      ENDIF
      prevDir = pvDir
   ENDIF
ENDIF
//-----------------------------------------------------------//
//-----ESCANEO MULTINIVEL (solo cuando hay pivote nuevo)-----//
IF newPivot = 1 AND npv >= 5 THEN
   
   startK = npv - mxPivots
   IF startK < 0 THEN
      startK = 0
   ENDIF
   nw = 0
   FOR k = startK TO npv - 1 DO
      $wI[nw] = $zI[k]
      $wP[nw] = $zP[k]
      $wH[nw] = $zH[k]
      nw = nw + 1
   NEXT
   
   FOR lev = 0 TO mxLevel DO
      
      IF nw >= 5 AND lev >= mnLevel THEN
         
         // --- ultimos 5 pivotes de la ventana de trabajo ---
         i0 = nw - 5
         i1 = nw - 4
         i2 = nw - 3
         i3 = nw - 2
         i4 = nw - 1
         x0 = $wI[i0]
         y0 = $wP[i0]
         x1 = $wI[i1]
         y1 = $wP[i1]
         x2 = $wI[i2]
         y2 = $wP[i2]
         x3 = $wI[i3]
         y3 = $wP[i3]
         x4 = $wI[i4]
         y4 = $wP[i4]
         
         // --- checkBarRatio sobre pivotes pares (P0,P2,P4) ---
         brOk = 1
         IF useBR = 1 THEN
            d1 = abs(x2 - x0)
            d2 = abs(x4 - x2)
            IF d1 > 0 THEN
               rbar = d2 / d1
               IF rbar < brLimit OR rbar > 1 / brLimit THEN
                  brOk = 0
               ENDIF
            ELSE
               brOk = 0
            ENDIF
         ENDIF
         
         IF brOk = 1 THEN
            // firstDirection: si P0 esta por encima de P1, P0 es un high
            IF y0 > y1 THEN
               firstDir = 1
            ELSE
               firstDir = -1
            ENDIF
            
            // ================= INSPECT DE LAS DOS LINEAS =================
            // ln=1 pivotes pares (P0,P2,P4) dir=firstDir ; ln=2 impares (P1,P3) dir=-firstDir
            valid1 = 0
            valid2 = 0
            L1ax = 0
            L1ay = 0
            L1bx = 0
            L1by = 0
            L2ax = 0
            L2ay = 0
            L2bx = 0
            L2by = 0
            
            FOR lnIdx = 1 TO 2 DO
               IF lnIdx = 1 THEN
                  ncand = 3
                  lnDir = firstDir
                  // cand 0: P0-P4 (otro P2) ; 1: P0-P2 (otro P4) ; 2: P2-P4 (otro P0)
                  $ca1x[0] = x0
                  $ca1y[0] = y0
                  $ca2x[0] = x4
                  $ca2y[0] = y4
                  $caox[0] = x2
                  $ca1x[1] = x0
                  $ca1y[1] = y0
                  $ca2x[1] = x2
                  $ca2y[1] = y2
                  $caox[1] = x4
                  $ca1x[2] = x2
                  $ca1y[2] = y2
                  $ca2x[2] = x4
                  $ca2y[2] = y4
                  $caox[2] = x0
               ELSE
                  ncand = 1
                  lnDir = 0 - firstDir
                  $ca1x[0] = x1
                  $ca1y[0] = y1
                  $ca2x[0] = x3
                  $ca2y[0] = y3
                  $caox[0] = x1
               ENDIF
               
               bestScr = 0 - 1
               bestVld = 0
               bAx = 0
               bAy = 0
               bBx = 0
               bBy = 0
               
               FOR c = 0 TO ncand - 1 DO
                  lx1 = $ca1x[c]
                  ly1 = $ca1y[c]
                  lx2 = $ca2x[c]
                  ly2 = $ca2y[c]
                  xo = $caox[c]
                  slp = (ly2 - ly1) / (lx2 - lx1)
                  vld = 1
                  scr = 0
                  tot = 0
                  brk = 0
                  FOR bi = x0 TO x4 DO
                     IF brk = 0 THEN
                        tot = tot + 1
                        oo = $barO[bi]
                        hh = $barH[bi]
                        ll = $barL[bi]
                        cc = $barC[bi]
                        IF lnDir > 0 THEN
                           barP = hh
                           barOut = ll
                        ELSE
                           barP = ll
                           barOut = hh
                        ENDIF
                        linP = ly1 + slp * (bi - lx1)
                        bodyMin = min(oo * lnDir, cc * lnDir)
                        IF linP * lnDir < bodyMin THEN
                           vld = 0
                           brk = 1
                        ELSE
                           IF linP * lnDir >= barOut * lnDir AND linP * lnDir <= barP * lnDir THEN
                              scr = scr + 1
                           ELSE
                              IF bi = xo THEN
                                 vld = 0
                                 brk = 1
                              ENDIF
                           ENDIF
                        ENDIF
                     ENDIF
                  NEXT
                  okc = 0
                  IF vld = 1 AND tot > 0 THEN
                     IF scr / tot < errRatio THEN
                        okc = 1
                     ENDIF
                  ENDIF
                  IF okc = 1 AND scr > bestScr THEN
                     bestScr = scr
                     bestVld = 1
                     bAx = lx1
                     bAy = ly1
                     bBx = lx2
                     bBy = ly2
                  ENDIF
               NEXT
               
               IF lnIdx = 1 THEN
                  valid1 = bestVld
                  L1ax = bAx
                  L1ay = bAy
                  L1bx = bBx
                  L1by = bBy
               ELSE
                  valid2 = bestVld
                  L2ax = bAx
                  L2ay = bAy
                  L2bx = bBx
                  L2by = bBy
               ENDIF
            NEXT
            // =============== FIN INSPECT ===============
            IF valid1 = 1 AND valid2 = 1 THEN
               // precios de cada linea en firstIndex(x0) y lastIndex(x4)
               s1 = (L1by - L1ay) / (L1bx - L1ax)
               s2 = (L2by - L2ay) / (L2bx - L2ax)
               t1a = L1ay + s1 * (x0 - L1ax)
               t1b = L1ay + s1 * (x4 - L1ax)
               t2a = L2ay + s2 * (x0 - L2ax)
               t2b = L2ay + s2 * (x4 - L2ax)
               
               // ---------- CLASIFICACION (resolvePatternName) ----------
               // upAng/loAng: razon de precios normalizada de cada linea.
               // Guard div/0 (en Pine da na inofensivo; en PRT rompe): den=0 -> ang=1 (plano)
               IF t1a > t2a THEN
                  mn0 = min(t2a, t2b)
                  mx0 = max(t1a, t1b)
                  denU = t1a - mn0
                  denL = t2a - mx0
                  IF denU <> 0 THEN
                     upAng = (t1b - mn0) / denU
                  ELSE
                     upAng = 1
                  ENDIF
                  IF denL <> 0 THEN
                     loAng = (t2b - mx0) / denL
                  ELSE
                     loAng = 1
                  ENDIF
               ELSE
                  mn0 = min(t1a, t1b)
                  mx0 = max(t2a, t2b)
                  denU = t2a - mn0
                  denL = t1a - mx0
                  IF denU <> 0 THEN
                     upAng = (t2b - mn0) / denU
                  ELSE
                     upAng = 1
                  ENDIF
                  IF denL <> 0 THEN
                     loAng = (t1b - mx0) / denL
                  ELSE
                     loAng = 1
                  ENDIF
               ENDIF
               
               IF upAng > 1 + flatRatio THEN
                  upDir = 1
               ELSIF upAng < 1 - flatRatio THEN
                  upDir = 0 - 1
               ELSE
                  upDir = 0
               ENDIF
               IF loAng > 1 + flatRatio THEN
                  loDir = 0 - 1
               ELSIF loAng < 1 - flatRatio THEN
                  loDir = 1
               ELSE
                  loDir = 0
               ENDIF
               
               sDiff = abs(t1a - t2a)
               eDiff = abs(t1b - t2b)
               mnDiff = min(sDiff, eDiff)
               brDiff = x4 - x0
               pDiff = abs(sDiff - eDiff) / brDiff
               IF pDiff > 0 THEN
                  pcb = mnDiff / pDiff
               ELSE
                  pcb = 999999999
               ENDIF
               
               isExp = 0
               IF eDiff > sDiff THEN
                  isExp = 1
               ENDIF
               isCon = 0
               IF eDiff < sDiff THEN
                  isCon = 1
               ENDIF
               
               isCh = 0
               IF pcb > 2 * brDiff THEN
                  isCh = 1
               ENDIF
               IF isExp = 0 AND isCon = 0 THEN
                  isCh = 1
               ENDIF
               IF upDir = 0 AND loDir = 0 THEN
                  isCh = 1
               ENDIF
               
               // signos para invalid
               IF t1a - t2a > 0 THEN
                  sgS = 1
               ELSIF t1a - t2a < 0 THEN
                  sgS = 0 - 1
               ELSE
                  sgS = 0
               ENDIF
               IF t1b - t2b > 0 THEN
                  sgE = 1
               ELSIF t1b - t2b < 0 THEN
                  sgE = 0 - 1
               ELSE
                  sgE = 0
               ENDIF
               
               pType = 0
               IF sgS <> sgE THEN
                  pType = 0
               ELSIF isCh = 1 THEN
                  IF upDir > 0 AND loDir > 0 THEN
                     pType = 1
                  ELSIF upDir < 0 AND loDir < 0 THEN
                     pType = 2
                  ELSE
                     pType = 3
                  ENDIF
               ELSIF isExp = 1 THEN
                  IF upDir > 0 AND loDir > 0 THEN
                     pType = 4
                  ELSIF upDir < 0 AND loDir < 0 THEN
                     pType = 5
                  ELSIF upDir > 0 AND loDir < 0 THEN
                     pType = 6
                  ELSIF upDir > 0 AND loDir = 0 THEN
                     pType = 7
                  ELSIF upDir = 0 AND loDir < 0 THEN
                     pType = 8
                  ELSE
                     pType = 0
                  ENDIF
               ELSE
                  IF upDir > 0 AND loDir > 0 THEN
                     pType = 9
                  ELSIF upDir < 0 AND loDir < 0 THEN
                     pType = 10
                  ELSIF upDir < 0 AND loDir > 0 THEN
                     pType = 11
                  ELSIF loDir = 0 THEN
                     IF upDir < 0 THEN
                        pType = 12
                     ELSE
                        pType = 1
                     ENDIF
                  ELSIF upDir = 0 THEN
                     IF loDir > 0 THEN
                        pType = 13
                     ELSE
                        pType = 2
                     ENDIF
                  ELSE
                     pType = 0
                  ENDIF
               ENDIF
               // ---------- FIN CLASIFICACION ----------
               okType = 0
               IF pType >= 1 AND pType <= 13 THEN
                  IF $allowed[pType] = 1 THEN
                     okType = 1
                  ENDIF
               ENDIF
               
               IF okType = 1 THEN
                  // dedup / overlap contra patrones ya registrados
                  skip = 0
                  IF npt > 0 THEN
                     FOR q = 0 TO npt - 1 DO
                        IF $ptX0[q] = x0 AND $ptX4[q] = x4 THEN
                           skip = 1
                        ENDIF
                        IF avoidOv = 1 THEN
                           // descartar si los tramos [x0,x4] y [ptX0,ptX4] se solapan
                           IF x0 < $ptX4[q] AND x4 > $ptX0[q] THEN
                              skip = 1
                           ENDIF
                        ENDIF
                     NEXT
                  ENDIF
                  
                  IF skip = 0 THEN
                     // direccion del ultimo pivote (P4 respecto a P3)
                     IF y4 > y3 THEN
                        pLastDir = 1
                     ELSE
                        pLastDir = 0 - 1
                     ENDIF
                     
                     // FIFO
                     IF npt >= mxPat AND npt > 0 THEN
                        FOR q = 0 TO npt - 2 DO
                           $ptX0[q] = $ptX0[q+1]
                           $ptY0[q] = $ptY0[q+1]
                           $ptX1[q] = $ptX1[q+1]
                           $ptY1[q] = $ptY1[q+1]
                           $ptX2[q] = $ptX2[q+1]
                           $ptY2[q] = $ptY2[q+1]
                           $ptX3[q] = $ptX3[q+1]
                           $ptY3[q] = $ptY3[q+1]
                           $ptX4[q] = $ptX4[q+1]
                           $ptY4[q] = $ptY4[q+1]
                           $ptT1a[q] = $ptT1a[q+1]
                           $ptT1b[q] = $ptT1b[q+1]
                           $ptT2a[q] = $ptT2a[q+1]
                           $ptT2b[q] = $ptT2b[q+1]
                           $ptType[q] = $ptType[q+1]
                           $ptDir[q] = $ptDir[q+1]
                        NEXT
                        npt = npt - 1
                     ENDIF
                     
                     $ptX0[npt] = x0
                     $ptY0[npt] = y0
                     $ptX1[npt] = x1
                     $ptY1[npt] = y1
                     $ptX2[npt] = x2
                     $ptY2[npt] = y2
                     $ptX3[npt] = x3
                     $ptY3[npt] = y3
                     $ptX4[npt] = x4
                     $ptY4[npt] = y4
                     $ptT1a[npt] = t1a
                     $ptT1b[npt] = t1b
                     $ptT2a[npt] = t2a
                     $ptT2b[npt] = t2b
                     $ptType[npt] = pType
                     $ptDir[npt] = pLastDir
                     npt = npt + 1
                  ENDIF
               ENDIF
            ENDIF
         ENDIF
         
         // --- construir el zigzag del nivel siguiente ---
         IF lev < mxLevel THEN
            nv = 0
            FOR k = 0 TO nw - 1 DO
               keep = 1
               IF k < nw - 1 THEN
                  IF k >= 2 THEN
                     prevSame = $wP[k-2]
                     IF $wH[k] = 1 THEN
                        IF $wP[k] < prevSame THEN
                           keep = 0
                        ENDIF
                     ELSE
                        IF $wP[k] > prevSame THEN
                           keep = 0
                        ENDIF
                     ENDIF
                  ENDIF
                  IF k + 2 <= nw - 1 THEN
                     nextSame = $wP[k+2]
                     IF $wH[k] = 1 THEN
                        IF $wP[k] < nextSame THEN
                           keep = 0
                        ENDIF
                     ELSE
                        IF $wP[k] > nextSame THEN
                           keep = 0
                        ENDIF
                     ENDIF
                  ENDIF
               ENDIF
               
               IF keep = 1 THEN
                  doPush = 1
                  IF nv > 0 THEN
                     prevH = $vH[nv-1]
                     IF prevH = $wH[k] THEN
                        doPush = 0
                        prevP = $vP[nv-1]
                        IF $wH[k] = 1 THEN
                           IF $wP[k] > prevP THEN
                              $vP[nv-1] = $wP[k]
                              $vI[nv-1] = $wI[k]
                           ENDIF
                        ELSE
                           IF $wP[k] < prevP THEN
                              $vP[nv-1] = $wP[k]
                              $vI[nv-1] = $wI[k]
                           ENDIF
                        ENDIF
                     ENDIF
                  ENDIF
                  IF doPush = 1 THEN
                     $vI[nv] = $wI[k]
                     $vP[nv] = $wP[k]
                     $vH[nv] = $wH[k]
                     nv = nv + 1
                  ENDIF
               ENDIF
            NEXT
            
            FOR k = 0 TO nv - 1 DO
               $wI[k] = $vI[k]
               $wP[k] = $vP[k]
               $wH[k] = $vH[k]
            NEXT
            nw = nv
         ENDIF
      ENDIF
   NEXT
ENDIF
//-----------------------------------------------------------//
//-----DIBUJO (solo en la ultima barra)----------------------//
IF islastbarupdate THEN
   IF npt > 0 THEN
      FOR k = 0 TO npt - 1 DO
         fx = $ptX0[k]
         lx = $ptX4[k]
         t1a = $ptT1a[k]
         t1b = $ptT1b[k]
         t2a = $ptT2a[k]
         t2b = $ptT2b[k]
         ptp = $ptType[k]
         
         // color por grupo: canal gris, cuna naranja, triangulo azul
         IF ptp <= 3 THEN
            cr = 120
            cg = 120
            cb = 120
         ELSIF ptp = 4 OR ptp = 5 OR ptp = 9 OR ptp = 10 THEN
            cr = 255
            cg = 149
            cb = 0
         ELSE
            cr = 74
            cg = 159
            cb = 245
         ENDIF
         
         // dos lineas de tendencia
         drawsegment(fx, t1a, lx, t1b) coloured(cr, cg, cb) style(line, 2)
         drawsegment(fx, t2a, lx, t2b) coloured(cr, cg, cb) style(line, 2)
         
         // zigzag interno del patron (5 pivotes -> 4 segmentos)
         IF shZig = 1 THEN
            drawsegment($ptX0[k], $ptY0[k], $ptX1[k], $ptY1[k]) coloured(zzr, zzg, zzb) style(dottedline, 1)
            drawsegment($ptX1[k], $ptY1[k], $ptX2[k], $ptY2[k]) coloured(zzr, zzg, zzb) style(dottedline, 1)
            drawsegment($ptX2[k], $ptY2[k], $ptX3[k], $ptY3[k]) coloured(zzr, zzg, zzb) style(dottedline, 1)
            drawsegment($ptX3[k], $ptY3[k], $ptX4[k], $ptY4[k]) coloured(zzr, zzg, zzb) style(dottedline, 1)
         ENDIF
         
         // etiquetas de pivote 1..5
         IF shPivL = 1 THEN
            lbl = 1
            drawtext("#lbl#", $ptX0[k], $ptY0[k]) coloured(cr, cg, cb)
            lbl = 2
            drawtext("#lbl#", $ptX1[k], $ptY1[k]) coloured(cr, cg, cb)
            lbl = 3
            drawtext("#lbl#", $ptX2[k], $ptY2[k]) coloured(cr, cg, cb)
            lbl = 4
            drawtext("#lbl#", $ptX3[k], $ptY3[k]) coloured(cr, cg, cb)
            lbl = 5
            drawtext("#lbl#", $ptX4[k], $ptY4[k]) coloured(cr, cg, cb)
         ENDIF
         
         // nombre del patron en el ultimo pivote
         IF shPatL = 1 THEN
            tx = $ptX4[k]
            ty = $ptY4[k]
            IF ptp = 1 THEN
               drawtext("Ascending Channel", tx, ty) coloured(cr, cg, cb)
            ELSIF ptp = 2 THEN
               drawtext("Descending Channel", tx, ty) coloured(cr, cg, cb)
            ELSIF ptp = 3 THEN
               drawtext("Ranging Channel", tx, ty) coloured(cr, cg, cb)
            ELSIF ptp = 4 THEN
               drawtext("Rising Wedge (Expanding)", tx, ty) coloured(cr, cg, cb)
            ELSIF ptp = 5 THEN
               drawtext("Falling Wedge (Expanding)", tx, ty) coloured(cr, cg, cb)
            ELSIF ptp = 6 THEN
               drawtext("Diverging Triangle", tx, ty) coloured(cr, cg, cb)
            ELSIF ptp = 7 THEN
               drawtext("Ascending Triangle (Expanding)", tx, ty) coloured(cr, cg, cb)
            ELSIF ptp = 8 THEN
               drawtext("Descending Triangle (Expanding)", tx, ty) coloured(cr, cg, cb)
            ELSIF ptp = 9 THEN
               drawtext("Rising Wedge (Contracting)", tx, ty) coloured(cr, cg, cb)
            ELSIF ptp = 10 THEN
               drawtext("Falling Wedge (Contracting)", tx, ty) coloured(cr, cg, cb)
            ELSIF ptp = 11 THEN
               drawtext("Converging Triangle", tx, ty) coloured(cr, cg, cb)
            ELSIF ptp = 12 THEN
               drawtext("Descending Triangle (Contracting)", tx, ty) coloured(cr, cg, cb)
            ELSIF ptp = 13 THEN
               drawtext("Ascending Triangle (Contracting)", tx, ty) coloured(cr, cg, cb)
            ENDIF
         ENDIF
      NEXT
   ENDIF
ENDIF
//-----------------------------------------------------------//
return

Download
Filename: PRC_Auto-Chart-Patterns.itf
Downloads: 6
Iván González Legend
Operating in the shadows, I hack problems one by one. My bio is currently encrypted by a complex algorithm. Decryption underway...
Author’s Profile

Comments

Logo Logo
Loading...