Elliott Impulse Engine [WillyAlgoTrader]📊 Elliott Impulse Engine (EIE) is an overlay indicator that counts a full Elliott cycle — impulse 0-1-2-3-4-5 plus correction A-B-C — completely automatically, using a Change-of-Character (CHoCH) trigger to start each count, a strict state machine to accept every wave point, Fibonacci target boxes to show where the next point is expected, a dashed "ghost" projection of the entire remaining path, and a trailing red invalidation line that tells you the exact price where the current count dies.
The core insight: most Elliott Wave tools either repaint their labels endlessly or force you to draw everything by hand. EIE does neither. It treats every count as a hypothesis : a CHoCH break seeds it, each confirmed pivot advances it one wave at a time, and a single hard price level can kill it. When the hypothesis dies, the chart is wiped clean and the engine waits for the next CHoCH — no stale labels, no silent redrawing of history. You always know three things at a glance: what wave the market is in, where price should go next, and where the idea is wrong.
Works on any symbol and any timeframe. Free and open for everyone.
🧩 WHY THESE COMPONENTS WORK TOGETHER
A ZigZag alone gives you swings but no wave logic. A Fibonacci tool alone gives you levels but no structure. A CHoCH detector alone tells you the trend flipped but not what comes next. And a manual Elliott count gives you structure but demands hours of drawing and constant re-labeling.
EIE chains all of these into one pipeline:
Swing structure engine → CHoCH detection → count seeding (point 0 + point 1) → fib grid on leg 0-1 → target boxes for points 2/3/4 → pivot-based point acceptance with soft-marking → ghost projection of the remaining path → trailing invalidation level → reset with a stated reason
The swing engine finds structural highs and lows. A confirmed close through a swing level against the previous trend is a CHoCH — the only event allowed to start a new count, so counts always begin at genuine structure shifts, not random noise. The moment leg 0-1 is confirmed, the engine builds a Fibonacci grid on that leg and projects the whole expected structure forward as a dashed ghost path. Each subsequent wave point is accepted from a separate, faster pivot stream, checked against its expected fib range, and either labeled clean ("2") or soft-marked ("2~") if it landed outside the range. At every state the engine maintains exactly one critical price — the trailing invalidation level — and if price breaks it, the count is declared dead with an explicit reason (BELOW_0, BELOW_W2, W3_SHORTEST, and so on), the markup is wiped, and the engine returns to scanning.
No single public tool does this loop. The combination turns Elliott counting from a subjective drawing exercise into a rule-driven process you can watch unfold bar by bar.
🔍 WHAT MAKES IT ORIGINAL
1️⃣ CHoCH-seeded counting — every count starts at a real structure break.
The engine tracks swing highs and lows using symmetric pivots (default 10 bars left / 10 bars right). A break is registered only on a confirmed bar close through the swing level. If that break goes against the current internal trend, it is a CHoCH — and only then does the engine arm a new count: point 0 is set to the extreme of the run that preceded the break, and the engine waits for a with-trend pivot beyond the CHoCH level to lock point 1.
Anti-noise guards built into the seeding:
— a warm-up gate (no CHoCH before max(3 × swing length, 50) bars of history),
— an optional cooldown (N bars after any count ends before a new CHoCH may seed),
— a level lock: after an invalidation, the same CHoCH level cannot immediately re-seed a new count (compared with half-a-tick tolerance, so floating-point equality can never leak a duplicate seed).
Why this matters: counts started from random pivots produce random labels. Counts started from structure breaks start where trend logic actually changed.
2️⃣ Non-blocking Fibonacci ranges with soft-marking — geometry informs, price decides.
Each wave point has an expected fib range measured on the 0→1 grid (retracement for 2, negative extension beyond point 1 for 3, 5 and B; point 4 uses its own 2→3 grid; C uses 0→1 again):
— Point 2: 0.5 – 0.705 (retracement of 0→1)
— Point 3: −0.5 – −0.618 (extension beyond point 1)
— Point 4: 0.5 – 0.705 (retracement of leg 2→3)
— Point 5: −0.618 – −1.0
— Point B: −0.5 – −0.618
— Point C: 0.0 – 0.236
The fib level of any price p on the 0→1 grid is computed as L = (p1 − p) / (p1 − p0); on the 2→3 grid as F = (p3 − p) / (p3 − p2). A pivot inside its range is labeled clean ("3"); a pivot outside it is still accepted but soft-marked ("3~") — because in real markets a valid wave frequently overshoots textbook levels. Only the hard invalidation rules can reject a point. Every range is a user input (min/max per point), so you can tighten or widen the geometry to your market.
Why this matters: strict-range engines discard perfectly good structure; free-form engines accept garbage. Soft-marking keeps the count honest while telling you visually which points are textbook and which are stretched.
3️⃣ Ghost projection — the whole remaining path drawn before it happens.
As soon as leg 0-1 is confirmed, EIE draws a dashed projection of every remaining point: 2? 3? 4? 5? A? B? C?. Each ghost point is placed inside its fib range at a position you choose (Middle of the range, Near edge, or Far edge), and spaced horizontally at step = round((b1 − b0) × coefficient) bars — i.e., the time geometry of the projection scales with the actual duration of leg 0-1. Ghost point 5? sits at extension −1.0 plus a configurable offset.
The projection is re-anchored from every newly accepted real point : once point 2 locks, the ghost path redraws starting from the real 2; once point 3 locks, from the real 3, and so on. Point 4's ghost is computed on the 2→3 grid using the best available references (real points when confirmed, ghost estimates before that).
Why this matters: you see the expected shape of the entire move — including the A-B-C correction after the impulse — while the impulse is still in wave 2.
4️⃣ Trailing invalidation level — one red line that answers "where am I wrong?".
At every state the engine maintains exactly one critical level, drawn as a dashed red line with an "INVALID + price" label:
— waiting for 1 / wave 2 in progress: point 0
— wave 3 before point 1 is broken: point 0; after the break: point 2
— wave 4: point 2
— wave 5 before point 3 is broken: point 2; after the break: point 4
— correction A/B/C: point 2
A break of this level resets the hypothesis with a named reason. The check runs every bar, before pivot processing , so a violent bar cannot both break the invalidation level and sneak a new wave point into the count on the same bar. Wick-driven pivots that slip past a close-based check are caught by a second, pivot-level guard (a pivot beyond point 2 / point 4 in the protected phases also triggers the reset). Classic Elliott rules are enforced on top: wave 2 may never retrace below point 0, wave 4 may never enter below point 2, and if wave 3 turns out shortest among 1, 3 and 5 at the moment point 5 is proposed, the count is rejected with reason W3_SHORTEST.
Why this matters: an Elliott count without a falsification level is a story, not a hypothesis. EIE makes the falsification price explicit on every bar.
5️⃣ Two-speed pivot system — stable structure, fast confirmation.
Structure and CHoCH run on the main swing length (default 10/10). Wave points 1-5 and A-C are accepted from a separate, shorter pivot stream (default 5/5, always ≤ swing length — validated at load). This decouples two jobs that a single pivot length cannot do well simultaneously: the long pivots keep the structural skeleton stable, the short pivots confirm wave points with roughly half the lag.
A dedicated backfill scan (up to ~480 bars) closes the pivot-lag gap for point 2: when point 1 locks or repositions, the engine re-scans all bars since point 1 for the true retracement extreme, so the best low/high inside the confirmation window is never missed. If price breaks point 1 before any counter-trend pivot confirmed point 2, the tracked extreme itself is accepted as point 2 and wave 3 is activated immediately.
Why this matters: one pivot length forces a trade-off between stability and speed. Two lengths plus a backfill scan give you both.
6️⃣ Repositioning logic — labels refine forward, never silently rewrite history.
Until the next wave locks, the engine allows controlled repositioning: a higher high repositions point 1 (rebuilding the grid and the point-2 box on the new geometry), a deeper pullback repositions point 2 (only until point 1 is broken — after the break, a deeper pivot is an invalidation, not a reposition), point 3 extends while wave 4 forms, point 4 deepens until point 3 is broken, point 5 extends during the correction, A deepens until B appears, B rises until C appears. Every reposition deletes and redraws only the affected segment and label, and the associated target box and its center line are rebuilt on the fresh grid — no stale geometry is left behind.
Why this matters: this is the honest middle ground between "repaints everything" and "freezes wrong labels forever". The rules for what may move, and until when, are fixed and stated.
7️⃣ OTE target boxes for points 2, 3 and 4 — the next objective is always a zone, not a guess.
When point 1 locks, a yellow box covering the point-2 fib range appears with a dashed center line at the range midpoint. When point 2 locks, the point-3 target box (on the extension side) appears. When point 3 locks, the point-4 box appears on the 2→3 grid. Each box extends forward a configurable number of bars (default 20) and its right edge snaps to the bar where the point actually forms. Box fill transparency adapts to the theme (65 dark / 55 light); the border and center line stay fully opaque.
Why this matters: "wave 4 should come" is vague. "Wave 4 is expected inside this drawn box, centered here" is actionable.
8️⃣ Explicit reset reasons + persistent CHoCH history — the chart tells you why.
Every count ends with a machine reason: FALSE_CHOCH (price broke back through point 0 before point 1 formed), BELOW_0, BELOW_W2, BELOW_W4, W3_SHORTEST, DEEP_C (correction retraced beyond point 2), TIMEOUT (optional: state lasted longer than k × leg 0-1 duration), B_ABOVE_5 (the "correction" broke above point 5 — the impulse is closed as done), or DONE (point C accepted, full cycle complete). On invalidation a ✖ marker with the reason in its tooltip is placed on the bar, and the dashboard keeps showing the last reason.
The active markup is wiped on reset — but CHoCH lines and labels live on a separate persistent layer (FIFO history, up to 100, default 50). When price later closes back through a CHoCH level, that line is clipped to the mitigation bar and turns dotted. So your chart accumulates a clean structural map of every trend change while dead counts disappear.
A special same-bar case is handled explicitly: if a reset and a fresh opposite CHoCH land on the same bar (with cooldown off), the engine wipes first, then seeds the new count on that same bar — the new hypothesis is never lost to ordering.
Why this matters: most auto-counters just vanish or redraw without explanation. EIE always states its reason, and the CHoCH map survives as context.
9️⃣ Anti-repaint discipline — confirmed pivots, close-confirmed breaks, honest Wick mode.
Three independent mechanisms:
— All pivot values are consumed only on confirmed bars: a forming real-time bar can make a pivot flicker, so transient pivot values are masked out and can never trigger an irreversible state transition. Historical bars are unaffected (they are all confirmed).
— In the default Close confirmation mode, invalidation breaks and wave-top breaks are evaluated only on the confirmed bar close — an intrabar excursion of the close cannot fire a reset that "un-happens" seconds later.
— The optional Wick mode reacts to any intrabar touch — faster, and by design irreversible within the bar. This is stated openly so you can choose speed vs. strictness.
Zone-entry events (price entering the point-2 OTE zone, the point-4 box, or tagging the −1.0 target) intentionally use wick extremes — a touch is a touch — and are one-way flags.
🔟 Theme-adaptive visual system with auto-contrast labels.
Theme is Auto-detected from the chart background (or forced Dark/Light). By default, long counts use a theme-adaptive green (dark green on light charts, bright green on dark charts) and short counts use red. If you enable custom colors, label text color is derived from the luminance of your chosen background — luma = 0.299R + 0.587G + 0.114B, threshold 140 — so digits stay readable on any shade you pick. The fib grid uses role-based color inputs (red 0.236, teal 0.705 OTE, blue retracement levels, gray round levels), all editable. Label font size is selectable from Tiny to Huge.
⚡ HOW IT WORKS — CALCULATION FLOW
Step 1 — Structure scan: Symmetric pivots (default 10/10) maintain the latest swing high and swing low; the engine also tracks the running extreme since the last swing (the future point 0).
Step 2 — CHoCH: A confirmed close through a swing level against the internal trend flips the trend and — if the engine is idle, cooled down, and the level is not locked — seeds a count: direction, CHoCH level, point 0.
Step 3 — Point 1: The first fast pivot beyond the CHoCH level becomes point 1. The 0→1 fib grid, the point-2 target box, and the full ghost projection are drawn.
Step 4 — Impulse counting: Fast counter-trend pivots propose points 2 and 4; fast with-trend pivots propose 3 and 5. Each is checked against its fib range (clean or "~"), each unlocks the next state, target boxes appear for the next objective, and the ghost path re-anchors from every real point.
Step 5 — Hard rules per bar: Before any pivot is processed, the trailing invalidation level is checked (Close or Wick mode). Wave 2 below point 0, wave 4 below point 2, a broken point 4 in late wave 5, or a shortest wave 3 all kill the count with a named reason.
Step 6 — Impulse complete: Point 5 accepted → the impulse counter increments and the engine rolls into correction tracking.
Step 7 — Correction A-B-C: A forms on a counter-trend pivot, B on a with-trend pivot (a B at or beyond point 5 closes the whole structure as B_ABOVE_5 instead), C completes the cycle → DONE.
Step 8 — Reset: On any ending — invalidation or completion — the active markup is wiped, the cooldown starts, and the engine returns to scanning. CHoCH history stays.
📖 HOW TO USE
🎯 Quick start (works even if you have never counted a wave):
1. Add the indicator to a clean chart. Nothing to configure — defaults are ready to use.
2. Wait for a CHoCH label. That is the engine saying: "the trend character just changed, I am watching for a new impulse here."
3. When labels 0 and 1 appear, the count is live. The dashed gray path with 2? 3? 4? 5? A? B? C? is the expected roadmap of the entire move.
4. Watch the yellow box — that is where the next wave point is expected. The dashed line inside it is the center of the zone.
5. Keep one eye on the red dashed INVALID line at all times. If price breaks it, the count is over — a ✖ appears, the markup clears, and the engine starts hunting for the next CHoCH. Hover the ✖ to read the exact reason.
👁️ Reading the chart:
— 🟢 Green numbered labels (0, 1, 2, 3, 4, 5) = accepted impulse points of a long count; red labels = a short count. Letters A, B, C = the correction.
— A label with ~ (like "2~") = the point is accepted, but it landed outside its textbook fib range — the count continues, treat it with slightly more caution.
— Solid colored path = confirmed structure. Dashed gray path with "?" labels = the ghost projection of what is still expected.
— 🟡 Yellow boxes = target zones for points 2, 3 and 4, each with a dashed center line.
— Dotted horizontal grid = the Fibonacci grid of leg 0-1 (retracements 0.236…1.0 above, extensions −0.5 / −0.618 / −1.0 below), each level labeled with its ratio and price.
— 🔴 Red dashed line + "INVALID price" = the trailing invalidation level of the current count.
— Dashed horizontal CHoCH lines = historical structure breaks; a line that turns dotted has been mitigated (price closed back through it).
— ✖ = the count was invalidated on this bar (reason in the tooltip).
📊 Dashboard fields:
— State: current phase (Scanning / CHoCH · wait 1 / Wave 2…5 / Corr · A-B-C).
— Direction: Long, Short, or — when idle.
— Invalidation: the current critical price.
— Last Reset: why the previous count ended (reason, DONE, or B_ABOVE_5). Resets on chart reload.
— Impulses: completed 5-wave impulses on the loaded history. Resets on chart reload.
— TF: chart timeframe. Version: engine version.
🔧 Tuning guide:
— Counts appear too rarely: lower Swing Detection Length (structure forms faster, more CHoCH seeds) — or the market is simply ranging without character changes.
— Too many counts die instantly (FALSE_CHOCH / BELOW_0): raise Swing Detection Length, or add a Cooldown of 5-20 bars so the engine skips the chop right after a failed count.
— Points confirm too slowly: lower Point Confirmation (min 1); remember it must stay ≤ Swing Detection Length.
— Too many "~" soft marks: widen the fib ranges for those points — your market may simply run hotter than the defaults.
— Old counts hang around in dead phases: set Timeout k > 0 (e.g. 3.0) — any state lasting longer than k × the duration of leg 0-1 resets automatically.
— Chart feels crowded: toggle off the Fib Grid, OTE Boxes, or the Projection independently; reduce Historical CHoCH; shrink label font size.
⚙️ KEY SETTINGS
⚙️ Main Settings:
— Swing Detection Length (default 10): pivot length for structure and CHoCH. Higher = larger structure, fewer seeds.
— Point Confirmation, bars (default 5): the separate short pivot used to accept wave points. Must be ≤ swing length (validated).
— Breaks: Invalidation Mode (default Close): Close = confirmed bar close beyond the level (non-repainting); Wick = any intrabar touch (instant, irreversible within the bar).
📐 Point Ranges (fib): min/max expectation range per point — Point 2 (0.5–0.705), Point 3 (−0.5…−0.618), Point 4 (0.5–0.705 on the 2→3 grid), Point 5 (−0.618…−1.0), Point B (−0.5…−0.618), Point C (0–0.236). All validated at load (2 and 4 must be inside (0,1); 3, 5, B must be negative; C inside [0,1); no zero-width ranges).
👻 Ghost Projection:
— Show Projection (on), Point Inside Range (Middle / Near / Far), Time Step Coef (default 1.0 × leg 0-1 duration), 5?: Offset From −1.0 (default 0.05).
♻️ Reset:
— Cooldown After Reset, bars (default 0 = off) and Timeout, k × leg 0-1 (default 0 = off; in the wait-for-1 phase the timeout scales on swing length instead, since no leg exists yet).
🎨 Visual Settings: Theme (Auto / Dark / Light), Fib Grid toggle, OTE Boxes toggle, CHoCH layer toggle, Path Width (2), Box Length Forward (20), Historical CHoCH max (50), Label Font Size (Tiny…Huge), Watermark toggle.
📏 Grid Levels: individual on/off for 0.236, 0.382, 0.5, 0.618, 0.705, 0.786, 0.886, 1.0, −0.5, −0.618, −1.0.
🎨 Colors: Use Custom Colors switch (off = theme-adaptive defaults), long/short point label backgrounds (text auto-contrasts), target box color, path and ghost colors, bull/bear CHoCH colors, and role-based fib grid colors.
📊 Dashboard: on/off, position (5 anchors), font size (the version row renders one step smaller).
🔔 ALERTS
Ten alert conditions covering the full lifecycle:
— 🟢 1. CHoCH + projection — CHoCH confirmed, movement projection built
— 🟡 2. Price in W2 OTE — price entered the point-2 zone
— 🟢 3. Point 2 accepted
— 🟢 4. Break of point 1 — wave 3 active
— 🟡 5. Price in W4 box
— 🟢 6. Break of point 3 — wave 5 active
— 🎯 7. Target −1.0 reached
— 🟢 8. Impulse complete — point 5 locked
— 🎯 9. Target C — correction complete, full cycle done
— 🔴 10. Invalidation — hypothesis reset
In addition, the engine fires dynamic alert() messages on every reset and on B_ABOVE_5 completion, including the reason text. In Close mode these announce on confirmed bar close; in Wick mode once per bar.
⚠️ IMPORTANT NOTES
— 🚫 No repainting of confirmed structure. Pivots use equal left/right lookback and their values are consumed only on confirmed bars; CHoCH breaks require a confirmed close; in the default Close mode, invalidation and wave-top breaks are evaluated on confirmed closes only. A pivot is, by nature, confirmed N bars after the actual extreme — the indicator draws from the confirmed bar backward to the true swing point. This is delayed confirmation, not repainting of settled values.
— 📐 Controlled repositioning is part of the design. Until the next wave locks, the latest point may legitimately move to a more extreme pivot (e.g., point 1 to a higher high). The rules for what may move, and until when, are fixed and described above. Wick mode reacts intrabar by design and is irreversible within the bar.
— 📊 The Impulses counter and Last Reset field are computed on loaded chart history and reset when the chart reloads.
— ⚖️ EIE counts one impulse degree at a time from the latest CHoCH. It does not label nested sub-waves, diagonals, or complex W-X-Y corrections — it is a focused impulse + zigzag engine, and the fib ranges reflect one practical interpretation of Elliott guidelines, which you can re-tune.
— 🛠️ This is a wave-counting and projection tool, not an automated trading system. It identifies structure, projects expected zones, and shows the invalidation price — trade decisions remain yours.
— 🌐 Works on all markets (crypto, forex, stocks, indices, commodities) and all timeframes.
Indicator







