À propos du screener : oui, c’est faisable, et non, cela n’existe pas. Il existe des codes publiés sur PRC qui détectent les triangles ou les biseaux de façon visuelle, mais aucun ne chaîne la séquence complète de Zanger.
Ce serait bien que, lorsque vous demandez de l’aide pour la programmation d’un indicateur/screener, vous soyez un peu plus concis sur les détails et la logique. Et si vous pouvez ajouter des images de ce que vous cherchez, c’est encore mieux 🙂
J’ai fait des recherches sur la séquence de Zanger et voici ce que j’en ai tiré au clair…
- Premier breakout — clôture au-dessus du plus haut des 40 sessions précédentes, bougie haussière, volume > 1,5× la moyenne des 20.
- Congestion — entre 4 et 25 sessions plus tard ; amplitude ≤ 12 % de son propre plus haut ; le plus bas se maintient au-dessus du niveau cassé (avec 2 % de tolérance pour les mèches) ; volume moyen de la congestion < 0,85× la moyenne. C’est le dessèchement du volume, la signature du modèle.
- Second breakout — clôture au-dessus du plus haut de la congestion avec un volume > 1,3× la moyenne.
C’est exactement ce que j’ai programmé. Vous verrez qu’il n’y a presque pas de valeurs qui apparaissent car les conditions sont très restrictives… C’est la raison pour laquelle je n’ai pas programmé de motif concret. Vous pouvez le faire visuellement avec les valeurs qui apparaissent.
Voici le code du screener et de l’indicateur pour voir visuellement de quoi nous parlons 🙂
//--------------------------------------------------//
//PRC_Zanger Double Breakout Screener
//version = 1
//31.07.2026
//Ivan Gonzalez @ www.prorealcode.com
//Sharing ProRealTime knowledge
//--------------------------------------------------//
// Etape 1 : premier breakout d'un plus haut de "lookback" barres, avec volume
// Etape 2 : congestion serree (drapeau / triangle / tasse-anse), volume qui s'asseche
// Etape 3 : second breakout du plus haut de la congestion, avec volume
//--------------------------------------------------//
// --- Inputs ---
//--------------------------------------------------//
selMode = 0 // 0 = les deux / 1 = en congestion / 2 = second breakout du jour
lookback = 40 // fenetre du plus haut casse par le 1er breakout
volLen = 20 // longueur de la moyenne de volume
volBrk1 = 1.5 // volume mini du 1er breakout (x moyenne)
volBrk2 = 1.3 // volume mini du 2eme breakout (x moyenne)
volDry = 0.85 // volume moyen pendant la congestion (x moyenne)
congMin = 4 // duree mini de la congestion, en barres
congMax = 25 // duree maxi de la congestion, en barres
maxWidth = 12 // largeur maxi de la congestion, en % de son plus haut
tolHold = 2 // tolerance sous le niveau casse, en %
minLiq = 200000 // liquidite mini : volume moyen x cours
//--------------------------------------------------//
// --- Contexte ---
//--------------------------------------------------//
vavg = average[volLen](volume)
ma50 = average[50](close)
hh = highest[lookback](high)
enoughBars = barindex > lookback + congMax + 60
trendOK = close > ma50 AND ma50 > ma50[10]
liqOK = vavg * close > minLiq
//--------------------------------------------------//
// --- Etape 1 : le premier breakout le plus recent ---
//--------------------------------------------------//
brkBar = 0
IF enoughBars THEN
FOR i = congMin TO congMax DO
IF brkBar = 0 AND close[i] > hh[i+1] AND close[i] > open[i] AND volume[i] > volBrk1 * vavg[i] THEN
brkBar = i
ENDIF
NEXT
ENDIF
//--------------------------------------------------//
// --- Etape 2 : geometrie et volume de la congestion ---
//--------------------------------------------------//
brkLevel = 0
consHi = 0
consLo = 0
volSum = 0
volCong = 0
widthPct = 0
dist = 0
IF brkBar > 0 THEN
brkLevel = hh[brkBar+1]
consHi = high[1]
consLo = low[1]
FOR j = 1 TO brkBar DO
IF high[j] > consHi THEN
consHi = high[j]
ENDIF
IF j < brkBar THEN
IF low[j] < consLo THEN
consLo = low[j]
ENDIF
volSum = volSum + volume[j]
ENDIF
NEXT
volCong = volSum / (brkBar - 1)
widthPct = (consHi - consLo) / consHi * 100
dist = (consHi / close - 1) * 100
ENDIF
tightOK = widthPct <= maxWidth
holdOK = consLo > brkLevel * (1 - tolHold / 100)
dryOK = volCong < volDry * vavg
congOK = brkBar > 0 AND tightOK AND holdOK AND dryOK AND trendOK AND liqOK
//--------------------------------------------------//
// --- Etape 3 : second breakout ---
//--------------------------------------------------//
etatVal = 0
IF congOK THEN
IF close > consHi AND volume > volBrk2 * vavg THEN
etatVal = 2
ELSIF close <= consHi THEN
etatVal = 1
ENDIF
ENDIF
filtre = 0
IF selMode = 0 AND etatVal > 0 THEN
filtre = 1
ELSIF selMode = 1 AND etatVal = 1 THEN
filtre = 1
ELSIF selMode = 2 AND etatVal = 2 THEN
filtre = 1
ENDIF
SCREENER[filtre > 0](etatVal AS "Etat", brkBar AS "Age", widthPct AS "Largeur %", dist AS "% trigger")
Indicador:
//--------------------------------------------------//
//PRC_Zanger Double Breakout
//version = 1
//31.07.2026
//Ivan Gonzalez @ www.prorealcode.com
//Sharing ProRealTime knowledge
//--------------------------------------------------//
// Version graphique du screener PRC_Zanger Double Breakout.
// Meme logique, meme parametres : ce que le screener remonte,
// c'est exactement ce qui est dessine ici.
// A inserer SUR LE PRIX (on price), pas en panneau separe.
//--------------------------------------------------//
// --- Inputs ---
//--------------------------------------------------//
lookback = 40 // fenetre du plus haut casse par le 1er breakout
volLen = 20 // longueur de la moyenne de volume
volBrk1 = 1.5 // volume mini du 1er breakout (x moyenne)
volBrk2 = 1.3 // volume mini du 2eme breakout (x moyenne)
volDry = 0.85 // volume moyen pendant la congestion (x moyenne)
congMin = 4 // duree mini de la congestion, en barres
congMax = 25 // duree maxi de la congestion, en barres
maxWidth = 12 // largeur maxi de la congestion, en % de son plus haut
tolHold = 2 // tolerance sous le niveau casse, en %
minLiq = 200000 // liquidite mini : volume moyen x cours (0 = desactive)
maxSetups = 10 // nombre de configurations conservees a l'ecran
//--------------------------------------------------//
// --- Contexte (identique au screener) ---
//--------------------------------------------------//
vavg = average[volLen](volume)
ma50 = average[50](close)
hh = highest[lookback](high)
atrOff = averagetruerange[14](close) * 0.6
enoughBars = barindex > lookback + congMax + 60
trendOK = close > ma50 AND ma50 > ma50[10]
liqOK = vavg * close > minLiq
//--------------------------------------------------//
// --- Etape 1 : le premier breakout le plus recent ---
//--------------------------------------------------//
brkBar = 0
IF enoughBars THEN
FOR i = congMin TO congMax DO
IF brkBar = 0 AND close[i] > hh[i+1] AND close[i] > open[i] AND volume[i] > volBrk1 * vavg[i] THEN
brkBar = i
ENDIF
NEXT
ENDIF
//--------------------------------------------------//
// --- Etape 2 : geometrie et volume de la congestion ---
//--------------------------------------------------//
brkLevel = 0
consHi = 0
consLo = 0
volSum = 0
volCong = 0
widthPct = 0
impLo = 0
IF brkBar > 0 THEN
brkLevel = hh[brkBar+1]
impLo = low[brkBar]
consHi = high[1]
consLo = low[1]
FOR j = 1 TO brkBar DO
IF high[j] > consHi THEN
consHi = high[j]
ENDIF
IF j < brkBar THEN
IF low[j] < consLo THEN
consLo = low[j]
ENDIF
volSum = volSum + volume[j]
ENDIF
NEXT
volCong = volSum / (brkBar - 1)
widthPct = (consHi - consLo) / consHi * 100
ENDIF
tightOK = widthPct <= maxWidth
holdOK = consLo > brkLevel * (1 - tolHold / 100)
dryOK = volCong < volDry * vavg
congOK = brkBar > 0 AND tightOK AND holdOK AND dryOK AND trendOK AND liqOK
//--------------------------------------------------//
// --- Etape 3 : second breakout ---
//--------------------------------------------------//
etatVal = 0
IF congOK THEN
IF close > consHi AND volume > volBrk2 * vavg THEN
etatVal = 2
ELSIF close <= consHi THEN
etatVal = 1
ENDIF
ENDIF
//--------------------------------------------------//
// --- Memoire des configurations (ring buffer FIFO) ---
//--------------------------------------------------//
ONCE nSet = 0
IF congOK THEN
curX1 = barindex - brkBar
IF nSet = 0 THEN
isNew = 1
ELSIF $sx1[nSet] <> curX1 THEN
isNew = 1
ELSE
isNew = 0
ENDIF
IF isNew = 1 THEN
WHILE nSet >= maxSetups DO
FOR k = 1 TO nSet - 1 DO
$sx1[k] = $sx1[k+1]
$sy1[k] = $sy1[k+1]
$sx2[k] = $sx2[k+1]
$sx3[k] = $sx3[k+1]
$shi[k] = $shi[k+1]
$slo[k] = $slo[k+1]
$slev[k] = $slev[k+1]
NEXT
nSet = nSet - 1
WEND
nSet = nSet + 1
$sx1[nSet] = curX1
$sy1[nSet] = impLo - atrOff
$slev[nSet] = brkLevel
$sx3[nSet] = 0
ENDIF
// tant que la configuration n'est pas declenchee, la boite respire
IF $sx3[nSet] = 0 OR $sx3[nSet] = barindex THEN
$sx2[nSet] = barindex - 1
$shi[nSet] = consHi
$slo[nSet] = consLo
IF etatVal = 2 THEN
$sx3[nSet] = barindex
ELSE
$sx3[nSet] = 0
ENDIF
ENDIF
ENDIF
//--------------------------------------------------//
// --- Dessin ---
//--------------------------------------------------//
IF islastbarupdate THEN
IF nSet > 0 THEN
FOR k = 1 TO nSet DO
IF $sx3[k] > 0 THEN
cr = 0
cg = 200
cb = 83
ELSE
cr = 255
cg = 171
cb = 0
ENDIF
// niveau casse par le 1er breakout : ancienne resistance = support
DRAWSEGMENT($sx1[k] - 8, $slev[k], $sx2[k] + 4, $slev[k]) COLOURED(120, 144, 156, 220) STYLE(dottedline, 1)
// boite de congestion
DRAWRECTANGLE($sx1[k] + 1, $shi[k], $sx2[k], $slo[k]) COLOURED(cr, cg, cb, 230) FILLCOLOR(cr, cg, cb, 40)
// premier breakout
DRAWTEXT("B1", $sx1[k], $sy1[k]) COLOURED(cr, cg, cb, 255)
IF $sx3[k] > 0 THEN
// second breakout confirme
DRAWTEXT("B2", $sx3[k], $shi[k] + atrOff) COLOURED(0, 200, 83, 255)
ELSE
// seuil de declenchement encore a franchir
DRAWSEGMENT($sx2[k], $shi[k], $sx2[k] + 6, $shi[k]) COLOURED(cr, cg, cb, 255) STYLE(dottedline, 2)
ENDIF
NEXT
ENDIF
ENDIF
RETURN