Student Wyckoff · Elliott Wave

Blog and practice

Elliott data and code lab: MT4, MT5, Pine and Python

Three educational examples for completed OHLC, confirmed pivots and six-point price checks.

Student Wyckoff editorial team

Published: (UTC+3)

Русский · English · Deutsch · Español · Français · Italiano · 繁體中文 · 日本語 · 한국어

Define the input, bar order and availability time before coding a count. These original examples implement separate operations, not a complete Elliott detector. They neither establish Pro/Light integration nor send orders.

MT4, MT5 and MQL5: an OHLC data contract

In MQL4/MQL5, CopyRates start_pos=0 includes the unfinished current bar. This example requests three D1 bars from position 1. Require exactly 3 returned bars; errors or incomplete history downloads require stopping and rechecking. ArraySetAsSeries(false) reads oldest first; CopyRates puts oldest data first in physical memory regardless of the series flag.

Record symbol, broker timezone, session, adjustments, OHLC and volume units. Tick volume is not interchangeable with exchange trading volume. Obtaining MqlRates does not detect waves or establish a Pro-compatible CSV. Check the actual import format separately; this educational script is not a report of an executed terminal test.

void OnStart() {
  MqlRates rates[];
  ArraySetAsSeries(rates, false);
  int n = CopyRates(_Symbol, PERIOD_D1, 1, 3, rates);
  if(n != 3) { Print("Need 3 completed bars; received ", n); return; }
  for(int i=0; i<n; i++)
    Print(rates[i].time, " ", rates[i].open, " ", rates[i].high,
          " ", rates[i].low, " ", rates[i].close);
}

Pine Script: pivot time versus availability

ta.pivothigh(high,2,2) needs two bars to the right. A high at bar 10 becomes known at the close of 12. offset=-2 moves its picture to 10 without moving knowledge backwards. The label is created at confirmation and records both indices.

Create the alert through the interface after adding the script and verify closed-bar behavior. This fragment validates neither impulse subdivisions nor degrees or corrections. Separate native TradingView tools and this Pine example from ExtraLight: the current ExtraLight page says coming soon and paid access is not open.

//@version=6
indicator("Confirmed pivot record", overlay=true, max_labels_count=100)
p = ta.pivothigh(high, 2, 2)
confirmed = barstate.isconfirmed and not na(p)
plot(confirmed ? p : na, style=plot.style_cross, offset=-2)
if confirmed
    label.new(bar_index, high, str.format("pivot {0}; available {1}", bar_index-2, bar_index))
    alert("Confirmed high pivot", alert.freq_once_per_bar_close)

Python: CSV and a price-only check

csv.DictReader returns string fields; Decimal consumes the original string without an intermediate float. For a file use open(path,newline="",encoding="utf-8"). The six invented points illustrate only a subset of ordinary upward-impulse price constraints.

For 100→120→110→145→125→150, motive lengths are 20,35,25: wave 3 is not shortest and wave 4 stays above 120. Changing 125 to 119 fails non-overlap. True does not establish subdivisions, degree, pivot selection or profitability; diagonals need a different rule set.

The f>d test additionally limits this example to a non-truncated fifth. A truncated fifth can fail to exceed the third-wave high, so rejection by this function alone does not exclude another valid impulse.

import csv, io
from decimal import Decimal as D

csv_text = "point,price\n0,100\n1,120\n2,110\n3,145\n4,125\n5,150\n"
with io.StringIO(csv_text, newline="") as stream:
    p = [D(row["price"]) for row in csv.DictReader(stream)]

def upward_price_subset(p):
    if len(p) != 6: return False
    a,b,c,d,e,f = p
    l1,l3,l5 = b-a,d-c,f-e
    return (b>a and a<c<b and d>b and b<e<d and f>d
            and l3 >= min(l1,l5))

assert upward_price_subset(p)
assert not upward_price_subset(p[:4]+[D("119"),p[5]])
print(upward_price_subset(p))  # True: price subset only

MT4 and MT5 indicators: identify the buffer contract

MQL4 iCustom returns a selected indicator-buffer value using mode and shift. MQL5 iCustom returns a handle; CopyBuffer retrieves its values. These interfaces do not prove that an unnamed custom indicator detects Elliott waves. Save the indicator file identity, inputs, buffer meaning, missing-value policy and completed-bar cutoff before interpreting a number.

Use the same broker series and saved bars for both runs. A ZigZag extreme, an Elliott label and a trade signal require different validation. Check delayed pivots and historical changes; keep an unresolved result unresolved. The earlier CopyRates example obtains data only. No particular custom binary, free licence, MT4/MT5 integration with Pro or automatic order behavior is asserted by this interface example.

InterfaceReturned object
MT4 / iCustomdouble: mode + shift
MT5 / iCustomhandle → CopyBuffer
P4=119 / P1=120No. The non-overlap check fails; other structural checks remain separate.

TradingView: formed patterns, settings and alert events

TradingView’s own Elliott Waves documentation describes impulse and zigzag searches over the last 600 bars. Its two label levels represent nesting, rather than automatically established historical Elliott degrees. Suitable pivots favour large price movements; the output is not every possible count. Documentation checked on 25 October 2026; no installed test in the user’s account is claimed.

Before a change, save the venue-qualified symbol, interval, scale, last closed bar, every input and a screenshot. In the alert dialog, choose this indicator as the condition and then one of its three documented event types. A part reported as formed is not a fully confirmed Elliott pattern. Availability depends on the account; access on a particular free plan is not promised here.

Setting or eventMeaning and reproducible check
Invert patternReverses the search direction: a downward impulse and an upward zigzag. Keep the same saved input window when switching.
In progressIncludes unfinished structures. Disable it to compare only patterns recognised as completed; subsequent data can still revise these.
Length type: Absolute / PercentAbsolute uses price differences; Percent uses relative changes. Freeze the choice because the ranking of lengths and rule checks can change.
Show projectionsShows possible next waves using Fibonacci references in In progress mode. A plotted projection is not an observed price.
Pivots / last wavePoints attach to suitable pivots; the running last wave uses a local high or low. Record when each point became available and every later relocation.
New patternA new pattern or a rebuild moving at least two points together; relocation of the very first point is excluded from that count.
New potential waveA new forming wave is added, or the last formed wave moves to another point and starts forming again.
Wave formedA previously forming wave has formed. Save time, selected event and state; this is not a return promise.
RecalculationNew data refine earlier patterns; any input change triggers full recalculation. Compare outputs against the same saved input window.

Sources and limits