Volume, Fibonacci & Elliott Wave
Level 5 — Mastery (cross-domain: math + quant + coding) Time limit: 90 minutes Total marks: 60
Instructions: Show all working. Where code is requested, pseudocode or Python is acceptable but must be logically complete. Use for math.
Question 1 — Fibonacci Geometry, Confluence & a Proof (24 marks)
A stock rallies in a clean impulse from a swing low to a swing high , then begins a corrective pullback.
(a) Compute the price levels of the standard Fibonacci retracements , , , and of the move. Give a general formula for the retracement level at ratio . (5)
(b) The golden ratio satisfies . Prove algebraically that the retracement ratio and the extension ratio , and hence show that ... more precisely prove the identity and that Derive exactly from . (6)
(c) After the correction ends at the retracement, the next impulse projects a Fibonacci extension. Using the ABC labelling where , , and is the retracement low, compute the and external extension targets measured as . (5)
(d) A horizontal support/resistance zone sits at –. Identify which Fibonacci retracement level(s) fall inside this zone and explain, in the language of confluence, why a trader treats an overlap of a Fib level and prior S/R as a higher-probability reaction zone than either alone. State one quantitative way to score confluence strength. (8)
Question 2 — Elliott Wave Structure, Rules & Volume Confirmation (22 marks)
(a) State the three inviolable rules of a 5-wave impulse (waves 1–5) and the two common guidelines (alternation, and equality/extension). Explain why breaking any one rule invalidates the count. (6)
(b) Consider the following price sequence forming a suspected impulse (prices at wave termini):
Wave 3 travels the length of wave 1; wave 4 retraces of wave 3. Compute and . Then verify all three impulse rules hold for your computed count. (9)
(c) Explain how volume should behave across a healthy impulse (waves 1–5) and across the corrective (A–B–C) phase, referencing accumulation/distribution and volume spread analysis. What volume signature would make you distrust a wave-3 breakout? (7)
Question 3 — Build an Algorithm: Automated Volume-Confirmed Fib Reaction Detector (14 marks)
You are given arrays high[], low[], close[], volume[] indexed by bar.
(a) Write pseudocode for a function fib_reaction_signal(swingLow, swingHigh, bars) that: (i) computes the 5 standard retracement levels, (ii) detects when close enters a tolerance band () around any level, and (iii) confirms a bullish reaction only if that bar's volume exceeds the 20-bar average volume by AND the bar closes in the upper third of its range (a VSA-style demand bar). Return the level touched and a boolean confirmation. (9)
(b) State the time complexity of your function per bar and explain one edge case (e.g., an uptrend vs downtrend swing) your sign conventions must handle. (5)
Answer keyMark scheme & solutions
Question 1
(a) Move size . Retracement level formula (measuring down from the high):
| 0.236 | |
| 0.382 | |
| 0.500 | |
| 0.618 | |
| 0.786 |
Marks: formula (1), each correct level (0.8 each ≈ 4). (5)
(b) Solve . (taking positive root). (2) From divide by : — this proves . (2) Also , and , so . (2) Trivially . (6)
(c) . Leg .
- target: .
- target: .
Marks: (1), each target (2). (5)
(d) The level lies just above the – zone; the closest confluence is the level (outside) — so within – none of the exact standard levels fall inside, but (122.92) is nearest, ~2 points above. A careful answer notes the zone slightly undercuts ; a reaction near – combines prior S/R (118–121) with the Fib, giving confluence. (award marks for reasoning even if noting the near-miss.)
Confluence argument: independent methods (structural S/R memory + Fibonacci proportion) predicting the same price zone means more market participants place orders there, so liquidity and probability of a reaction increase — a coincidence of signals raises posterior probability. Quantitative scoring: e.g. confluence score = number of independent levels within a fixed price window, or an inverse-distance weighted sum where is distance of each level from the test price.
Marks: identify nearest level & note zone position (3); confluence rationale (3); quantitative scoring method (2). (8)
Question 2
(a) Three inviolable rules (2 each):
- Wave 2 never retraces more than 100% of wave 1 (cannot go below wave 1 start).
- Wave 3 is never the shortest of the three impulse waves (1,3,5).
- Wave 4 does not overlap the price territory of wave 1 (in a standard impulse; end of 4 must not enter wave-1 range).
Guidelines: alternation (if wave 2 is sharp, wave 4 is sideways, and vice-versa); equality/extension (typically one impulse wave extends—often wave 3—and the other two tend toward equality). Breaking a rule means the labelling is structurally impossible, so the count must be redrawn. (6)
(b) Wave 1 length . Wave 3 length , starting from : Wave 4 retraces of wave 3 length: :
Rule check:
- Wave 2 = 56 > 50 (start), retrace ✓.
- Lengths: W1=12, W3=19.416, W5 . Wave 3 (19.42) is not the shortest ✓ (shortest is W1=12).
- Wave 4 low wave 1 high : no overlap ✓.
All three rules satisfied → valid impulse.
Marks: (2), (2), each rule check (1.5×3 ≈ 5). (9)
(c) Healthy impulse volume: highest on wave 3 (the strongest, most participated move — driven by accumulation completing and trend recognition); wave 1 moderate, wave 5 often on lower volume / divergence (fewer buyers, distribution begins). Corrections A–B–C run on lighter volume than impulses; wave C may spike as capitulation. Accumulation shows rising volume on up-bars with narrowing spreads at lows; distribution shows rising volume on up-bars that fail to make progress (wide spread, close off highs) near tops. Distrust a wave-3 breakout if it occurs on declining or below-average volume, or a wide-range up-bar closing in its lower third with high volume (no demand / supply overwhelming) — a VSA sign of weakness signalling a false breakout.
Marks: impulse volume pattern (3), corrective (2), distrust signature (2). (7)
Question 3
(a) Pseudocode:
function fib_reaction_signal(swingLow, swingHigh, bars):
move = swingHigh - swingLow
dir = sign(move) # +1 uptrend swing, -1 downtrend
ratios = [0.236,0.382,0.5,0.618,0.786]
levels = [swingHigh - r*move for r in ratios] # works for both dirs
tol = 0.003
for b in bars:
avgVol = mean(volume[b-20 .. b-1])
for (r, L) in zip(ratios, levels):
if abs(bars[b].close - L) <= tol * L:
rng = bars[b].high - bars[b].low
if rng == 0: continue
closePos = (bars[b].close - bars[b].low) / rng
volOK = bars[b].volume >= 1.5 * avgVol
bullVSA = closePos >= 2/3 # upper third
confirmed = volOK and bullVSA
return (L, confirmed)
return (None, False)
Marks: levels computation (2), tolerance band detection (2), volume ≥150% avg (2), upper-third close test (2), return structure (1). (9)
(b) Complexity: for each bar the 20-bar average is amortised (or maintain a running window), and the inner loop over 5 ratios is , so per bar, overall for bars. Edge case: swing direction — using swingHigh - r*move with signed move keeps the level formula valid whether the impulse is up (swingHigh>swingLow, retracements below high) or down (swingHigh<swingLow, "retracements" above the low), so dir prevents inverted level ordering; also guard (doji/no-range bar) to avoid division by zero.
Marks: complexity (2), edge-case explanation (3). (5)
[
{"claim":"61.8% retracement of 100->160 is 122.92","code":"H=160;L=100;lvl=H-0.618*(H-L);result=abs(lvl-122.92)<1e-9"},
{"claim":"1.618 extension target from C=122.92 is 220.00","code":"C=160-0.618*60;t=C+1.618*60;result=abs(t-220.0)<1e-9"},
{"claim":"phi solves x^2=x+1 giving 1.618...","code":"from sympy import sqrt,Rational; phi=(1+sqrt(5))/2; result=simplify(phi**2-phi-1)==0"},
{"claim":"1-1/phi = 1/phi^2 = 0.382","code":"from sympy import sqrt; phi=(1+sqrt(5))/2; result=simplify((1-1/phi)-(1/phi**2))==0 and abs(float(1-1/phi)-0.381966)<1e-4"},
{"claim":"Wave3=75.416, Wave4=68.0, W3 not shortest, no overlap","code":"W2=56;len1=12;W3=W2+1.618*len1;W4=W3-0.382*(1.618*len1);W5=90;lenW3=1.618*len1;lenW5=W5-W4;ok=(W4>62) and (lenW3>len1) and not(lenW3<len1 and lenW3<lenW5);result=abs(W3-75.416)<1e-3 and abs(W4-68.0)<1e-2 and ok"}
]