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.
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:
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:
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.
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.
//-----------------------------------------------------------//
//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