Elliott Wave 3 Screener

Category: Screeners By: Iván González Created: August 6, 2026, 4:19 PM
August 6, 2026, 4:19 PM
Screeners
0 Comments

1. Introduction

Counting Elliott waves across a watchlist does not scale. Even if you are quick at it, going instrument by instrument to find the two or three that have just confirmed a third wave takes an evening, and by the time you finish, the first ones you looked at have moved.

This ProScreener does that pass for you. It returns the instruments where an impulse count is live and currently in wave 3: the structure changed character, the first leg printed, the pullback was accepted as point 2, and price has since broken above point 1.

What makes that moment worth screening for is not the label. It is that three separate things are defined at once:

  • A direction — the one the live count is running in.
  • A known invalidation — point 2. If price returns there, the reading is dead, and the screener tells you the exact price.
  • A defined target — the -0.618 extension of leg 0-1.

So every name on the list arrives with an entry context, a stop and an objective already attached, rather than as a bare signal you still have to frame.

The screener runs the same engine as the Elliott Impulse Engine indicator (https://www.prorealcode.com/prorealtime-indicators/elliott-impulse-engine/), so anything it returns can be opened on a chart and inspected with the full count drawn out.

 

2. What the Screener Looks For

The condition is not a shape matched against past bars. It is the state of a machine that has walked through a specific sequence, in order:

Change of character. The engine tracks swing structure with a long pivot and keeps a standing bias — bullish once a swing high is closed through, bearish once a swing low is. A break in the same direction as that bias is just continuation and is ignored. Only a break against it opens a hypothesis. That is what seeds a count.

Point 0 and point 1. Point 0 is not the bar where the break happened: the engine has been tracking the running extreme of the swing in progress, and that extreme — a real turning point, with its real bar — becomes the origin. Point 1 is then the first confirmed pivot beyond the broken level.

Point 2. The pullback that follows. It is accepted using a second, shorter pivot length, which is what lets the engine catch turns inside a developing impulse without producing a change of character on every wiggle. A point 2 that lands outside its expected retracement band is still accepted — it is flagged, not discarded.

The break of point 1. This is the step that declares wave 3, and it is the screener’s condition. Until it happens, the count is a hypothesis about a pullback; after it, the market has confirmed the impulse is extending.

While all this runs, a single invalidation level ratchets forward with the count. During wave 3 it sits at point 2. A close beyond it and the whole reading is discarded — the instrument leaves the list on the next scan.

 

3. The Three Signal Modes

The same condition can be caught at three different moments of its life, set by sigMode:

Mode 0 — wave 3 just declared (default). Point 1 was broken maxBarsAge bars ago or less. This is the discovery mode: impulses that have just confirmed, with the move still ahead of them. It is the one to run daily.

Mode 1 — wave 3 in progress. Every live wave 3, regardless of when it started. Use it to see the full current inventory rather than only the fresh entries — useful the first time you run the screener on a new universe.

Mode 2 — price inside the target zone. Price has already reached the band between the -0.5 and -0.618 extensions of leg 0-1. This is not an entry mode: it is where an existing position starts thinking about the exit.

Two further filters narrow the list:

  • dirFilter restricts to longs or shorts, or leaves both.
  • strictW2 keeps only textbook counts — those where point 2 landed inside its expected 0.5 to 0.705 retracement band. Off by default, because a wave 2 that only retraces 0.38 is common in strong impulses and is worth seeing; the results table reports the measured value so you can judge it yourself.

4. Reading the Results

Eight columns come back with each hit:

  • Dir — 1 for a long count, -1 for a short one.
  • W3 fib% — where price sits on the fib scale of leg 0-1, as a percentage. Negative means beyond point 1, which is where a wave 3 belongs. The more negative, the more of the move is already behind you.
  • % to target — distance from price to the -0.618 extension, measured in the direction of the count. Positive means there is room left; negative means it has already run past it.
  • Invalidation — the price that kills the reading. This is the number to size a stop against, and it is the same value the indicator prints on the chart.
  • W2 retr% — how deep the point 2 pullback went on leg 0-1. Around 50 to 70 is textbook; below 38 is an impulse that barely corrected, which tends to be strong but leaves the invalidation far away.
  • W3 bars — bars elapsed since the break of point 1.
  • Impulses — completed five-wave impulses counted on the loaded history.
  • Reset code — why the previous count on that instrument ended: 1 timeout, 2 false change of character, 3 below point 0, 4 below point 2, 5 below point 4, 6 deep correction, 7 wave 3 was the shortest, 8 point B ran past point 5, 9 completed.

Sorting by % to target descending puts the names with the most theoretical room left on top. Sorting by W3 bars ascending puts the freshest first.

The two columns that earn their place beyond the obvious are W2 retr% and Invalidation. Together they tell you, before you open a single chart, whether a candidate is a tight setup with a close stop or a stretched one where being right still costs a lot to hold.

 

5. Screener Settings

Swing Detection Length (swingLen, default 10) — the structural pivot. This is the main character dial: raise it for larger and rarer structure with fewer counts, lower it for faster structure and more of them. On a daily chart, 10 gives multi-week impulses.

Point Confirmation (accDepth, default 5) — the short pivot that accepts the wave points. Keep it at or below the swing length. Lower values catch the turns of a developing impulse sooner, at the cost of accepting noisier points.

Invalidation Mode (confClose, default 1) — whether a level break needs a confirmed close beyond it, or counts on any wick touch. Close mode produces fewer and slower resets.

Fib ranges — the expected windows for points 2 and 3. Range 2 feeds the strictW2 filter; range 3 defines the target zone used by mode 2 and the % to target column. Changing range 3 changes what the screener calls the objective.

Cooldown After Reset (default 0) — bars to wait after any count ends before a new one may be seeded. Worth raising on noisy instruments where structure breaks cluster together.

Timeout (default 0, off) — discards a hypothesis that has sat in the same state longer than k times the duration of leg 0-1. A count that stops developing is usually a count that was wrong.

scanBack (default 480) — how far back the engine looks when recovering the extreme of a retracement. This is the main cost driver of the scan. It is deliberately left at the same value the indicator uses, so that both produce the same count; lowering it makes the screener faster but can drift its reading away from what you see on the chart.

 

6. A Note on Available History

ProScreener works on a fixed window: 1024 bars on Premium, 255 on Complete. That matters more here than in a simple screener, because the engine needs to warm up and then walk a full sequence — change of character, point 1, point 2, break — inside that window.

Two practical consequences:

On Complete, expect few results. Instruments genuinely in wave 3 will be missed simply because their point 0 falls outside the loaded window. Lowering swingLen shortens the sequence and helps, at the cost of noisier structure.

A chart usually holds more history than the scan. If a chart starts further back, its engine may seed a count in a place the screener never saw, and the two can legitimately end up in different states. That is why Impulses is exposed as a column: it should match the indicator’s dashboard. When it does not, the two are looking at different windows, and the chart is the one to trust.

The honest way to use the screener is therefore as a shortlist generator, not as a verdict: run it, then open the handful of names it returns and confirm the count on the chart before doing anything with it.

 

7. Elliott Wave 3 Screener Code

 

// ----------------------------------------------------
// PRC Elliott Impulse Engine - Wave 3 screener
// version = 0
// 05.08.2026
// Ivan Gonzalez @ www.prorealcode.com
// Sharing ProRealTime knowledge
// ----------------------------------------------------
// Filters instruments with an Elliott wave 3 IN PROGRESS, using the engine of
// the PRC_Elliott-Impulse-Engine indicator: CHoCH against the
// trend -> point 1 -> point 2 accepted -> point 1 broken.
// ----------------------------------------------------
//=== INPUTS: ENGINE ===
swingLen  = 10     // structural pivot, drives structure and CHoCH
accDepth  = 5      // short pivot, accepts points 1-5/A-C (<= swingLen)
confClose = 1      // 1 = confirm breaks on close, 0 = on the wick

//=== INPUTS: FIB RANGE OF EACH POINT ===
// The engine accepts the point whether or not it is in range; here range 2 feeds
// strictW2 and range 3 defines the target zone of wave 3
rng2Min = 0.5      // point 2: retracement of leg 0-1
rng2Max = 0.705
rng3Min = -0.5     // point 3: extension beyond point 1
rng3Max = -0.618
rng4Min = 0.5      // point 4: retracement of leg 2-3
rng4Max = 0.705

//=== INPUTS: SCREENER FILTERING ===
sigMode    = 0     // 0 = wave 3 just declared, 1 = wave 3 in progress, 2 = price inside target zone
maxBarsAge = 5     // maximum age of the point 1 break (mode 0 only)
dirFilter  = 0     // 0 = both directions, 1 = longs only, 2 = shorts only
strictW2   = 0     // 1 = require point 2 to have landed inside its expected range
scanBack   = 480   // cap of the backfill loops. 480 = SAME value as the
// indicator: lowering it speeds the screener up but can drift the
// count away from the one you see on the chart

//=== INPUTS: RESET ===
cooldownBars = 0   // bars to wait after a count ends before a CHoCH may seed
timeoutK     = 0.0 // reset if the state lasts longer than k x (leg 0-1 duration). 0 = off

//=== STATE (scalars: PRT rewinds them on every tick of the live bar) ===
// wState  0 = scanning   1 = CHoCH, waiting for 1   2..5 = waves 2 to 5   6/7/8 = A/B/C
ONCE wState = 0
ONCE wdir = 0
ONCE chLvl = 0
ONCE hasChLvl = 0
ONCE wp0 = 0
ONCE wp1 = 0
ONCE wp2 = 0
ONCE wp3 = 0
ONCE wp4 = 0
ONCE wp5 = 0
ONCE wpA = 0
ONCE wpB = 0
ONCE wb0 = 0
ONCE wb1 = 0
ONCE has0 = 0
ONCE has1 = 0
ONCE has2 = 0
ONCE has4 = 0
ONCE has5 = 0
ONCE soft2 = 0
ONCE p2Lvl = 0
ONCE brk1Bar = 0
ONCE broke1 = 0
ONCE broke3 = 0
ONCE ote2 = 0
ONCE oteB4 = 0
ONCE hitM1 = 0
ONCE w2best = 0
ONCE hasW2best = 0
ONCE lockedLvl = 0
ONCE hasLocked = 0
ONCE lastResetBar = 0 - 100000
ONCE stateStart = 0
ONCE impulses = 0
ONCE lastResetCode = 0
ONCE ewTrend = 0
ONCE swHi = 0
ONCE swLo = 0
ONCE swHiBar = 0
ONCE swLoBar = 0
ONCE hasSwHi = 0
ONCE hasSwLo = 0
ONCE swHiBroken = 0
ONCE swLoBroken = 0
ONCE curSHbar = 0
ONCE curSLbar = 0
ONCE hasCurSH = 0
ONCE hasCurSL = 0
ONCE runLo = 0
ONCE runLoBar = 0
ONCE runHi = 0
ONCE runHiBar = 0
ONCE hasRunLo = 0
ONCE hasRunHi = 0

//=== EVENT FLAGS FOR THIS BAR ===
pendingReset = 0    // 1 = invalidated, 2 = completed
resetCode = 0       // 1 TIMEOUT 2 FALSE_CHOCH 3 BELOW_0 4 BELOW_W2 5 BELOW_W4 6 DEEP_C 7 W3_SHORTEST 8 B_ABOVE_5 9 DONE
seedNow = 0
seedDefer = 0
seedDir = 0
seedLvl = 0
seedP0 = 0
seedB0 = 0
doAcc2 = 0
acc2P = 0
acc2Soft = 0
acc2Lvl = 0
acc2Brk = 0

//=== PIVOTS (two lengths: structure and point acceptance) ===
swPHok = 0
swPLok = 0
swPH = 0
swPL = 0
IF barindex > 2 * swingLen THEN
   IF high[swingLen] >= highest[2 * swingLen + 1](high) THEN
      swPH = high[swingLen]
      swPHok = 1
   ENDIF
   IF low[swingLen] <= lowest[2 * swingLen + 1](low) THEN
      swPL = low[swingLen]
      swPLok = 1
   ENDIF
ENDIF
swBarP = barindex - swingLen

phAok = 0
plAok = 0
phA = 0
plA = 0
IF barindex > 2 * accDepth THEN
   IF high[accDepth] >= highest[2 * accDepth + 1](high) THEN
      phA = high[accDepth]
      phAok = 1
   ENDIF
   IF low[accDepth] <= lowest[2 * accDepth + 1](low) THEN
      plA = low[accDepth]
      plAok = 1
   ENDIF
ENDIF
pivBA = barindex - accDepth

//=== CURRENT INVALIDATION LEVEL (evaluated BEFORE touching the pivots) ===
critOk = 0
critLvl = 0
critCode = 0
IF wState = 1 THEN
   critLvl = wp0
   critOk = has0
   critCode = 2
ELSIF wState = 2 THEN
   critLvl = wp0
   critOk = has0
   critCode = 3
ELSIF wState = 3 THEN
   IF broke1 = 1 THEN
      critLvl = wp2
      critOk = has2
      critCode = 4
   ELSE
      critLvl = wp0
      critOk = has0
      critCode = 3
   ENDIF
ELSIF wState = 4 THEN
   critLvl = wp2
   critOk = has2
   critCode = 4
ELSIF wState = 5 THEN
   IF broke3 = 1 THEN
      critLvl = wp4
      critOk = has4
      critCode = 5
   ELSE
      critLvl = wp2
      critOk = has2
      critCode = 4
   ENDIF
ELSIF wState >= 6 THEN
   critLvl = wp2
   critOk = has2
   critCode = 6
ENDIF

//=== 1. INVALIDATION CHECK ===
IF wState <> 0 THEN
   IF timeoutK > 0 AND has1 = 1 THEN
      IF barindex - stateStart > timeoutK * (wb1 - wb0) THEN
         pendingReset = 1
         resetCode = 1
      ENDIF
   ENDIF
   IF timeoutK > 0 AND wState = 1 THEN
      IF barindex - stateStart > timeoutK * swingLen THEN
         pendingReset = 1
         resetCode = 1
      ENDIF
   ENDIF
   IF pendingReset = 0 AND critOk = 1 THEN
      adverse = 0
      IF wdir = 1 THEN
         IF confClose = 1 THEN
            IF close < critLvl THEN
               adverse = 1
            ENDIF
         ELSE
            IF low < critLvl THEN
               adverse = 1
            ENDIF
         ENDIF
      ELSE
         IF confClose = 1 THEN
            IF close > critLvl THEN
               adverse = 1
            ENDIF
         ELSE
            IF high > critLvl THEN
               adverse = 1
            ENDIF
         ENDIF
      ENDIF
      IF adverse = 1 THEN
         pendingReset = 1
         resetCode = critCode
      ENDIF
   ENDIF
ENDIF

//=== 2. SWING STRUCTURE AND CHoCH ===
isWarmed = 0
IF barindex >= max(swingLen * 3, 50) THEN
   isWarmed = 1
ENDIF

IF swPHok = 1 THEN
   swHi = swPH
   swHiBar = swBarP
   hasSwHi = 1
   swHiBroken = 0
ENDIF
IF swPLok = 1 THEN
   swLo = swPL
   swLoBar = swBarP
   hasSwLo = 1
   swLoBroken = 0
ENDIF

// Running extreme of the current swing: it becomes point 0 of the next count
IF hasSwHi = 1 THEN
   newSH = 0
   IF hasCurSH = 0 THEN
      newSH = 1
   ELSIF swHiBar <> curSHbar THEN
      newSH = 1
   ENDIF
   IF newSH = 1 THEN
      curSHbar = swHiBar
      hasCurSH = 1
      offSH = min(barindex - swHiBar, scanBack)
      mLo = low
      mLoBar = barindex
      IF offSH > 0 THEN
         FOR k = 0 TO offSH DO
            IF low[k] < mLo THEN
               mLo = low[k]
               mLoBar = barindex - k
            ENDIF
         NEXT
      ENDIF
      runLo = mLo
      runLoBar = mLoBar
      hasRunLo = 1
   ELSIF low < runLo THEN
      runLo = low
      runLoBar = barindex
   ENDIF
ENDIF

IF hasSwLo = 1 THEN
   newSL = 0
   IF hasCurSL = 0 THEN
      newSL = 1
   ELSIF swLoBar <> curSLbar THEN
      newSL = 1
   ENDIF
   IF newSL = 1 THEN
      curSLbar = swLoBar
      hasCurSL = 1
      offSL = min(barindex - swLoBar, scanBack)
      mHi = high
      mHiBar = barindex
      IF offSL > 0 THEN
         FOR k = 0 TO offSL DO
            IF high[k] > mHi THEN
               mHi = high[k]
               mHiBar = barindex - k
            ENDIF
         NEXT
      ENDIF
      runHi = mHi
      runHiBar = mHiBar
      hasRunHi = 1
   ELSIF high > runHi THEN
      runHi = high
      runHiBar = barindex
   ENDIF
ENDIF

// Structure break on close. CHoCH = break against the standing trend
bullBreak = 0
IF hasSwHi = 1 AND swHiBroken = 0 AND isWarmed = 1 AND close > swHi THEN
   bullBreak = 1
ENDIF
bearBreak = 0
IF hasSwLo = 1 AND swLoBroken = 0 AND isWarmed = 1 AND close < swLo THEN
   bearBreak = 1
ENDIF

IF bullBreak = 1 THEN
   swHiBroken = 1
   wasBear = 0
   IF ewTrend = -1 THEN
      wasBear = 1
   ENDIF
   ewTrend = 1
   cooled = 0
   IF barindex >= lastResetBar + cooldownBars THEN
      cooled = 1
   ENDIF
   freeUp = 0
   IF hasLocked = 0 THEN
      freeUp = 1
   ELSIF abs(swHi - lockedLvl) > pipsize / 2 THEN
      freeUp = 1
   ENDIF
   IF wasBear = 1 AND wState = 0 AND pendingReset = 0 AND cooled = 1 AND freeUp = 1 AND hasRunLo = 1 THEN
      seedNow = 1
      seedDefer = 0
      seedDir = 1
      seedLvl = swHi
      seedP0 = runLo
      seedB0 = runLoBar
   ELSIF wasBear = 1 AND pendingReset = 1 AND cooldownBars = 0 AND freeUp = 1 AND hasRunLo = 1 THEN
      // Bull break on the same bar as a reset: deferred seed
      seedNow = 1
      seedDefer = 1
      seedDir = 1
      seedLvl = swHi
      seedP0 = runLo
      seedB0 = runLoBar
   ENDIF
ENDIF

IF bearBreak = 1 THEN
   swLoBroken = 1
   wasBull = 0
   IF ewTrend = 1 THEN
      wasBull = 1
   ENDIF
   ewTrend = -1
   cooledD = 0
   IF barindex >= lastResetBar + cooldownBars THEN
      cooledD = 1
   ENDIF
   freeDn = 0
   IF hasLocked = 0 THEN
      freeDn = 1
   ELSIF abs(swLo - lockedLvl) > pipsize / 2 THEN
      freeDn = 1
   ENDIF
   IF wasBull = 1 AND wState = 0 AND pendingReset = 0 AND cooledD = 1 AND freeDn = 1 AND hasRunHi = 1 THEN
      seedNow = 1
      seedDefer = 0
      seedDir = -1
      seedLvl = swLo
      seedP0 = runHi
      seedB0 = runHiBar
   ELSIF wasBull = 1 AND pendingReset = 1 AND cooldownBars = 0 AND freeDn = 1 AND hasRunHi = 1 THEN
      seedNow = 1
      seedDefer = 1
      seedDir = -1
      seedLvl = swLo
      seedP0 = runHi
      seedB0 = runHiBar
   ENDIF
ENDIF

// Immediate seed: the count starts on this very bar, so the pivot logic
// below can already accept point 1 today
IF seedNow = 1 AND seedDefer = 0 THEN
   wdir = seedDir
   chLvl = seedLvl
   hasChLvl = 1
   wp0 = seedP0
   wb0 = seedB0
   has0 = 1
   wState = 1
   stateStart = barindex
   hasW2best = 0
ENDIF

//=== 3. STATE LOGIC ON PIVOTS ===
// With-trend and counter-trend pivots: resolved with the ALREADY seeded direction
ctrOk = 0
ctrV = 0
wtOk = 0
wtV = 0
IF wdir = 1 THEN
   ctrOk = plAok
   ctrV = plA
   wtOk = phAok
   wtV = phA
ELSE
   ctrOk = phAok
   ctrV = phA
   wtOk = plAok
   wtV = plA
ENDIF

IF pendingReset = 0 AND wState = 1 THEN
   // Waiting for point 1: point 0 keeps running with counter-trend pivots
   IF ctrOk = 1 THEN
      deeper0 = 0
      IF wdir = 1 AND ctrV < wp0 THEN
         deeper0 = 1
      ENDIF
      IF wdir = -1 AND ctrV > wp0 THEN
         deeper0 = 1
      ENDIF
      IF deeper0 = 1 THEN
         wp0 = ctrV
         wb0 = pivBA
      ENDIF
   ENDIF
   IF wtOk = 1 THEN
      beyondCh = 0
      IF wdir = 1 AND wtV > chLvl THEN
         beyondCh = 1
      ENDIF
      IF wdir = -1 AND wtV < chLvl THEN
         beyondCh = 1
      ENDIF
      IF beyondCh = 1 THEN
         wp1 = wtV
         wb1 = pivBA
         has1 = 1
         wState = 2
         stateStart = barindex
         // Backfill the retracement extreme over the pivot lag window
         spanB = min(barindex - wb1 - 1, scanBack)
         bestV = low
         IF wdir = -1 THEN
            bestV = high
         ENDIF
         IF spanB > 0 THEN
            FOR k = 1 TO spanB DO
               vv = low[k]
               IF wdir = -1 THEN
                  vv = high[k]
               ENDIF
               betterV = 0
               IF wdir = 1 AND vv < bestV THEN
                  betterV = 1
               ENDIF
               IF wdir = -1 AND vv > bestV THEN
                  betterV = 1
               ENDIF
               IF betterV = 1 THEN
                  bestV = vv
               ENDIF
            NEXT
         ENDIF
         w2best = bestV
         hasW2best = 1
      ENDIF
   ENDIF
   
ELSIF pendingReset = 0 AND wState = 2 THEN
   // Relocate point 1 if a more extreme with-trend pivot shows up
   IF wtOk = 1 THEN
      higher1 = 0
      IF wdir = 1 AND wtV > wp1 THEN
         higher1 = 1
      ENDIF
      IF wdir = -1 AND wtV < wp1 THEN
         higher1 = 1
      ENDIF
      IF higher1 = 1 THEN
         wp1 = wtV
         wb1 = pivBA
         spanC = min(barindex - wb1 - 1, scanBack)
         bestV2 = low
         IF wdir = -1 THEN
            bestV2 = high
         ENDIF
         IF spanC > 0 THEN
            FOR k = 1 TO spanC DO
               vv2 = low[k]
               IF wdir = -1 THEN
                  vv2 = high[k]
               ENDIF
               better2 = 0
               IF wdir = 1 AND vv2 < bestV2 THEN
                  better2 = 1
               ENDIF
               IF wdir = -1 AND vv2 > bestV2 THEN
                  better2 = 1
               ENDIF
               IF better2 = 1 THEN
                  bestV2 = vv2
               ENDIF
            NEXT
         ENDIF
         w2best = bestV2
         hasW2best = 1
      ENDIF
   ENDIF
   IF ctrOk = 1 THEN
      den01 = wp1 - wp0
      lvl2 = 0
      IF den01 <> 0 THEN
         lvl2 = (wp1 - ctrV) / den01
      ENDIF
      IF lvl2 >= 1.0 THEN
         pendingReset = 1
         resetCode = 3
      ELSIF lvl2 > 0.0 THEN
         doAcc2 = 1
         acc2P = ctrV
         acc2Lvl = lvl2
         acc2Soft = 1
         IF lvl2 >= min(rng2Min, rng2Max) AND lvl2 <= max(rng2Min, rng2Max) THEN
            acc2Soft = 0
         ENDIF
      ENDIF
   ENDIF
   
ELSIF pendingReset = 0 AND wState = 3 THEN
   // Point 2 can only be relocated while point 1 has not been broken
   IF ctrOk = 1 THEN
      deeper2 = 0
      IF wdir = 1 AND ctrV < wp2 THEN
         deeper2 = 1
      ENDIF
      IF wdir = -1 AND ctrV > wp2 THEN
         deeper2 = 1
      ENDIF
      IF deeper2 = 1 AND broke1 = 1 THEN
         pendingReset = 1
         resetCode = 4
      ELSIF deeper2 = 1 THEN
         den02 = wp1 - wp0
         lvl2b = 0
         IF den02 <> 0 THEN
            lvl2b = (wp1 - ctrV) / den02
         ENDIF
         IF lvl2b >= 1.0 THEN
            pendingReset = 1
            resetCode = 3
         ELSE
            wp2 = ctrV
            p2Lvl = lvl2b
            soft2 = 1
            IF lvl2b >= min(rng2Min, rng2Max) AND lvl2b <= max(rng2Min, rng2Max) THEN
               soft2 = 0
            ENDIF
         ENDIF
      ENDIF
   ENDIF
   IF pendingReset = 0 AND wtOk = 1 AND broke1 = 1 THEN
      beyond3 = 0
      IF wdir = 1 AND wtV > wp1 THEN
         beyond3 = 1
      ENDIF
      IF wdir = -1 AND wtV < wp1 THEN
         beyond3 = 1
      ENDIF
      IF beyond3 = 1 THEN
         wp3 = wtV
         wState = 4
         stateStart = barindex
         oteB4 = 0
      ENDIF
   ENDIF
   
ELSIF pendingReset = 0 AND wState = 4 THEN
   // Relocate point 3 if the impulse extends
   IF wtOk = 1 THEN
      higher3 = 0
      IF wdir = 1 AND wtV > wp3 THEN
         higher3 = 1
      ENDIF
      IF wdir = -1 AND wtV < wp3 THEN
         higher3 = 1
      ENDIF
      IF higher3 = 1 THEN
         wp3 = wtV
      ENDIF
   ENDIF
   IF pendingReset = 0 AND ctrOk = 1 THEN
      below2 = 0
      IF wdir = 1 AND ctrV < wp2 THEN
         below2 = 1
      ENDIF
      IF wdir = -1 AND ctrV > wp2 THEN
         below2 = 1
      ENDIF
      den23 = wp3 - wp2
      fib4 = 0
      IF den23 <> 0 THEN
         fib4 = (wp3 - ctrV) / den23
      ENDIF
      IF below2 = 1 THEN
         pendingReset = 1
         resetCode = 4
      ELSIF fib4 > 0.0 THEN
         wp4 = ctrV
         has4 = 1
         wState = 5
         stateStart = barindex
         hitM1 = 0
      ENDIF
   ENDIF
   
ELSIF pendingReset = 0 AND wState = 5 THEN
   // Point 4 can deepen while point 3 has not been broken
   IF ctrOk = 1 AND broke3 = 0 THEN
      deeper4 = 0
      IF wdir = 1 AND ctrV < wp4 THEN
         deeper4 = 1
      ENDIF
      IF wdir = -1 AND ctrV > wp4 THEN
         deeper4 = 1
      ENDIF
      below2r = 0
      IF wdir = 1 AND ctrV < wp2 THEN
         below2r = 1
      ENDIF
      IF wdir = -1 AND ctrV > wp2 THEN
         below2r = 1
      ENDIF
      IF deeper4 = 1 AND below2r = 1 THEN
         pendingReset = 1
         resetCode = 4
      ELSIF deeper4 = 1 THEN
         wp4 = ctrV
      ENDIF
   ENDIF
   // Once point 3 is broken, a pivot beyond point 4 invalidates
   IF pendingReset = 0 AND ctrOk = 1 AND broke3 = 1 THEN
      beyond4 = 0
      IF wdir = 1 AND ctrV < wp4 THEN
         beyond4 = 1
      ENDIF
      IF wdir = -1 AND ctrV > wp4 THEN
         beyond4 = 1
      ENDIF
      IF beyond4 = 1 THEN
         pendingReset = 1
         resetCode = 5
      ENDIF
   ENDIF
   IF pendingReset = 0 AND wtOk = 1 AND broke3 = 1 THEN
      beyond5 = 0
      IF wdir = 1 AND wtV > wp3 THEN
         beyond5 = 1
      ENDIF
      IF wdir = -1 AND wtV < wp3 THEN
         beyond5 = 1
      ENDIF
      IF beyond5 = 1 THEN
         len1 = abs(wp1 - wp0)
         len3 = abs(wp3 - wp2)
         len5 = abs(wtV - wp4)
         IF len3 < len1 AND len3 < len5 THEN
            // Wave 3 cannot be the shortest of the impulse
            pendingReset = 1
            resetCode = 7
         ELSE
            wp5 = wtV
            has5 = 1
            wState = 6
            stateStart = barindex
            impulses = impulses + 1
         ENDIF
      ENDIF
   ENDIF
   
ELSIF pendingReset = 0 AND wState = 6 THEN
   // Wave 5 can still extend
   IF wtOk = 1 THEN
      higher5 = 0
      IF wdir = 1 AND wtV > wp5 THEN
         higher5 = 1
      ENDIF
      IF wdir = -1 AND wtV < wp5 THEN
         higher5 = 1
      ENDIF
      IF higher5 = 1 THEN
         wp5 = wtV
      ENDIF
   ENDIF
   IF pendingReset = 0 AND ctrOk = 1 THEN
      deepA = 0
      IF wdir = 1 AND ctrV < wp2 THEN
         deepA = 1
      ENDIF
      IF wdir = -1 AND ctrV > wp2 THEN
         deepA = 1
      ENDIF
      IF deepA = 1 THEN
         pendingReset = 1
         resetCode = 6
      ELSE
         wpA = ctrV
         wState = 7
         stateStart = barindex
      ENDIF
   ENDIF
   
ELSIF pendingReset = 0 AND wState = 7 THEN
   // Point A can deepen until B appears
   IF ctrOk = 1 THEN
      deeperA = 0
      IF wdir = 1 AND ctrV < wpA THEN
         deeperA = 1
      ENDIF
      IF wdir = -1 AND ctrV > wpA THEN
         deeperA = 1
      ENDIF
      deepHard = 0
      IF wdir = 1 AND ctrV < wp2 THEN
         deepHard = 1
      ENDIF
      IF wdir = -1 AND ctrV > wp2 THEN
         deepHard = 1
      ENDIF
      IF deeperA = 1 AND deepHard = 1 THEN
         pendingReset = 1
         resetCode = 6
      ELSIF deeperA = 1 THEN
         wpA = ctrV
      ENDIF
   ENDIF
   IF pendingReset = 0 AND wtOk = 1 THEN
      above5 = 0
      IF wdir = 1 AND wtV >= wp5 THEN
         above5 = 1
      ENDIF
      IF wdir = -1 AND wtV <= wp5 THEN
         above5 = 1
      ENDIF
      IF above5 = 1 THEN
         pendingReset = 2
         resetCode = 8
      ELSE
         wpB = wtV
         wState = 8
         stateStart = barindex
      ENDIF
   ENDIF
   
ELSIF pendingReset = 0 AND wState = 8 THEN
   // Point B can extend until C appears
   IF wtOk = 1 THEN
      above5b = 0
      IF wdir = 1 AND wtV >= wp5 THEN
         above5b = 1
      ENDIF
      IF wdir = -1 AND wtV <= wp5 THEN
         above5b = 1
      ENDIF
      higherB = 0
      IF wdir = 1 AND wtV > wpB THEN
         higherB = 1
      ENDIF
      IF wdir = -1 AND wtV < wpB THEN
         higherB = 1
      ENDIF
      IF above5b = 1 THEN
         pendingReset = 2
         resetCode = 8
      ELSIF higherB = 1 THEN
         wpB = wtV
      ENDIF
   ENDIF
   IF pendingReset = 0 AND ctrOk = 1 THEN
      deepC = 0
      IF wdir = 1 AND ctrV < wp2 THEN
         deepC = 1
      ENDIF
      IF wdir = -1 AND ctrV > wp2 THEN
         deepC = 1
      ENDIF
      IF deepC = 1 THEN
         pendingReset = 1
         resetCode = 6
      ELSE
         // Point C closes the correction on this very bar
         pendingReset = 2
         resetCode = 9
      ENDIF
   ENDIF
ENDIF

//=== 4. INTRABAR PROGRESS: ZONES AND BREAKS ===
IF pendingReset = 0 AND wState = 2 THEN
   ext2 = low
   IF wdir = -1 THEN
      ext2 = high
   ENDIF
   trackBest = 0
   IF hasW2best = 0 THEN
      trackBest = 1
   ELSIF wdir = 1 AND ext2 < w2best THEN
      trackBest = 1
   ELSIF wdir = -1 AND ext2 > w2best THEN
      trackBest = 1
   ENDIF
   IF trackBest = 1 THEN
      w2best = ext2
      hasW2best = 1
   ENDIF
   den09 = wp1 - wp0
   eLvl = 0
   IF den09 <> 0 THEN
      eLvl = (wp1 - ext2) / den09
   ENDIF
   IF ote2 = 0 AND eLvl >= min(rng2Min, rng2Max) THEN
      ote2 = 1
   ENDIF
   // Point 1 broken before point 2 is accepted: point 2 is the best extreme
   brk1now = 0
   IF wdir = 1 THEN
      IF confClose = 1 THEN
         IF close > wp1 THEN
            brk1now = 1
         ENDIF
      ELSE
         IF high > wp1 THEN
            brk1now = 1
         ENDIF
      ENDIF
   ELSE
      IF confClose = 1 THEN
         IF close < wp1 THEN
            brk1now = 1
         ENDIF
      ELSE
         IF low < wp1 THEN
            brk1now = 1
         ENDIF
      ENDIF
   ENDIF
   IF doAcc2 = 0 AND brk1now = 1 THEN
      lvlB2 = 0
      IF den09 <> 0 THEN
         lvlB2 = (wp1 - w2best) / den09
      ENDIF
      doAcc2 = 1
      acc2P = w2best
      acc2Lvl = lvlB2
      acc2Brk = 1
      acc2Soft = 1
      IF lvlB2 >= min(rng2Min, rng2Max) AND lvlB2 <= max(rng2Min, rng2Max) THEN
         acc2Soft = 0
      ENDIF
   ENDIF
ENDIF

// Unified acceptance of point 2
IF pendingReset = 0 AND doAcc2 = 1 THEN
   wp2 = acc2P
   has2 = 1
   soft2 = acc2Soft
   p2Lvl = acc2Lvl
   wState = 3
   stateStart = barindex
   IF acc2Brk = 1 THEN
      broke1 = 1
      brk1Bar = barindex
   ENDIF
ENDIF

IF pendingReset = 0 AND wState = 3 AND broke1 = 0 THEN
   brk1b = 0
   IF wdir = 1 THEN
      IF confClose = 1 THEN
         IF close > wp1 THEN
            brk1b = 1
         ENDIF
      ELSE
         IF high > wp1 THEN
            brk1b = 1
         ENDIF
      ENDIF
   ELSE
      IF confClose = 1 THEN
         IF close < wp1 THEN
            brk1b = 1
         ENDIF
      ELSE
         IF low < wp1 THEN
            brk1b = 1
         ENDIF
      ENDIF
   ENDIF
   IF brk1b = 1 THEN
      broke1 = 1
      brk1Bar = barindex
   ENDIF
ENDIF

IF pendingReset = 0 AND wState = 4 AND oteB4 = 0 THEN
   ext4 = low
   IF wdir = -1 THEN
      ext4 = high
   ENDIF
   den10 = wp3 - wp2
   extF = 0
   IF den10 <> 0 THEN
      extF = (wp3 - ext4) / den10
   ENDIF
   IF extF >= min(rng4Min, rng4Max) THEN
      oteB4 = 1
   ENDIF
ENDIF

IF pendingReset = 0 AND wState = 5 THEN
   IF broke3 = 0 THEN
      brk3now = 0
      IF wdir = 1 THEN
         IF confClose = 1 THEN
            IF close > wp3 THEN
               brk3now = 1
            ENDIF
         ELSE
            IF high > wp3 THEN
               brk3now = 1
            ENDIF
         ENDIF
      ELSE
         IF confClose = 1 THEN
            IF close < wp3 THEN
               brk3now = 1
            ENDIF
         ELSE
            IF low < wp3 THEN
               brk3now = 1
            ENDIF
         ENDIF
      ENDIF
      IF brk3now = 1 THEN
         broke3 = 1
      ENDIF
   ENDIF
   IF hitM1 = 0 THEN
      tgtM1 = wp1 + 1.0 * (wp1 - wp0)
      hitNow = 0
      IF wdir = 1 AND high >= tgtM1 THEN
         hitNow = 1
      ENDIF
      IF wdir = -1 AND low <= tgtM1 THEN
         hitNow = 1
      ENDIF
      IF hitNow = 1 THEN
         hitM1 = 1
      ENDIF
   ENDIF
ENDIF

IF pendingReset = 0 AND wState >= 7 AND has5 = 1 THEN
   brk5now = 0
   IF wdir = 1 THEN
      IF confClose = 1 THEN
         IF close > wp5 THEN
            brk5now = 1
         ENDIF
      ELSE
         IF high > wp5 THEN
            brk5now = 1
         ENDIF
      ENDIF
   ELSE
      IF confClose = 1 THEN
         IF close < wp5 THEN
            brk5now = 1
         ENDIF
      ELSE
         IF low < wp5 THEN
            brk5now = 1
         ENDIF
      ENDIF
   ENDIF
   IF brk5now = 1 THEN
      pendingReset = 2
      resetCode = 8
   ENDIF
ENDIF

//=== 5. RESET EXECUTION ===
IF pendingReset = 1 THEN
   IF hasChLvl = 1 THEN
      lockedLvl = chLvl
      hasLocked = 1
   ENDIF
ENDIF

IF pendingReset > 0 THEN
   lastResetBar = barindex
   lastResetCode = resetCode
   wState = 0
   wdir = 0
   hasChLvl = 0
   has0 = 0
   has1 = 0
   has2 = 0
   has4 = 0
   has5 = 0
   soft2 = 0
   broke1 = 0
   broke3 = 0
   ote2 = 0
   oteB4 = 0
   hitM1 = 0
   hasW2best = 0
ENDIF

//=== 6. DEFERRED SEED (CHoCH on the same bar as the reset) ===
// The invalidation marker of this bar is kept until the next seed
IF seedNow = 1 AND seedDefer = 1 THEN
   wdir = seedDir
   chLvl = seedLvl
   hasChLvl = 1
   wp0 = seedP0
   wb0 = seedB0
   has0 = 1
   wState = 1
   stateStart = barindex
   hasW2best = 0
ENDIF

//=== 7. INVALIDATION LEVEL FOR THE DASHBOARD AND THE DRAWING ===
dCritLvl = 0
IF wState = 1 OR wState = 2 THEN
   dCritLvl = wp0
ELSIF wState = 3 THEN
   IF broke1 = 1 THEN
      dCritLvl = wp2
   ELSE
      dCritLvl = wp0
   ENDIF
ELSIF wState = 4 THEN
   dCritLvl = wp2
ELSIF wState = 5 THEN
   IF broke3 = 1 THEN
      dCritLvl = wp4
   ELSE
      dCritLvl = wp2
   ENDIF
ELSIF wState >= 6 THEN
   dCritLvl = wp2
ENDIF

//=== 8. SCREENER CONDITION ===
// Wave 3 declared: point 2 accepted and point 1 broken
inW3 = 0
IF wState = 3 AND broke1 = 1 AND has2 = 1 THEN
   inW3 = 1
ENDIF

// Wave 3 progress on the 0-1 grid (negative = beyond point 1)
denW = wp1 - wp0
w3Lvl = 0
IF inW3 = 1 AND denW <> 0 THEN
   w3Lvl = (wp1 - close) / denW
ENDIF

// Wave 3 target and percentage distance in favour of the count
tgtPct = 0
inZone = 0
IF inW3 = 1 THEN
   tgt3 = wp1 - rng3Max * denW
   tgtPct = (tgt3 - close) / close * 100 * wdir
   z3a = wp1 - rng3Min * denW
   IF close >= min(z3a, tgt3) AND close <= max(z3a, tgt3) THEN
      inZone = 1
   ENDIF
ENDIF

ageW3 = barindex - brk1Bar

modeOk = 0
IF inW3 = 1 THEN
   IF sigMode = 0 AND ageW3 <= maxBarsAge THEN
      modeOk = 1
   ELSIF sigMode = 1 THEN
      modeOk = 1
   ELSIF sigMode = 2 AND inZone = 1 THEN
      modeOk = 1
   ENDIF
ENDIF

dirOk = 0
IF dirFilter = 0 THEN
   dirOk = 1
ELSIF dirFilter = 1 AND wdir = 1 THEN
   dirOk = 1
ELSIF dirFilter = 2 AND wdir = -1 THEN
   dirOk = 1
ENDIF

// Textbook count: point 2 landed inside its expected range
w2Ok = 1
IF strictW2 = 1 AND soft2 = 1 THEN
   w2Ok = 0
ENDIF

p2Pct = round(p2Lvl * 1000) / 10
w3Pct = round(w3Lvl * 1000) / 10
tgtShow = round(tgtPct * 10) / 10
critShow = round(dCritLvl * 100) / 100

SCREENER[modeOk = 1 AND dirOk = 1 AND w2Ok = 1](wdir AS "Dir", w3Pct AS "W3 fib%", tgtShow AS "% to target", critShow AS "Invalidation", p2Pct AS "W2 retr%", ageW3 AS "W3 bars", impulses AS "Impulses", lastResetCode AS "Reset code")

Download
Filename: SCR_Elliott-Impulse-Engine.itf
Downloads: 4
Iván González Legend
As an architect of digital worlds, my own description remains a mystery. Think of me as an undeclared variable, existing somewhere in the code.
Author’s Profile

Comments

Logo Logo
Loading...