Fibonacci Retracement: The Levels, the Swing, and the Function We Do Not Ship
A fibonacci retracement is five horizontal lines drawn between two prices you picked. That is the whole tool, and everything that follows on this page comes out of taking that sentence seriously.
Our engine has no function for it. None. I want that on the table before the arithmetic, because most pages on this subject imply a machine somewhere is finding these levels for you, and on our side of the wire no such machine exists. What does exist is the thing that picks the two prices, and that turns out to be where all the trouble lives.
What the arithmetic actually is
Take a swing: a low and a high, or a high and a low. Call them p0 and p1. Every level is one subtraction and one multiplication.
level(r) = p1 - r * (p1 - p0)
Run that with r set to 0.236, 0.382, 0.5, 0.618 and 0.786 and you have the standard set. There is no state, no window, no smoothing, nothing carried from bar to bar. Compared with the recursion inside an RSI or a moving average, this is a pocket calculator.
Two of those five ratios are not Fibonacci numbers, which nobody mentions. The 50% line is a half. The 78.6% line is the square root of 0.618, so it is a square root of a ratio rather than one of them. They sit on the toolbar because traders watch them, and that is a perfectly good reason — just not the reason usually given.
The function our engine does not ship
structure.rs defines, and the row that is not there. The engine finds swings; drawing ratios between them is a decision nobody automated.I checked the source rather than my memory, and the result is short.
crates/vike-indicators registers 171 indicators. Not one of them is a fibonacci retracement, extension, fan, arc or time zone. Searching the entire Rust workspace for fib returns five hits, all inside a vendored broker library, and all of them a reconnect backoff schedule — the Fibonacci sequence used to space out retry attempts, which has nothing to do with price.
There is exactly one 61.8 in the engine. It sits at registry.rs:1057, in the bands field of the Choppiness Index, next to a 38.2. Those are horizontal guide lines for an oscillator that runs from 0 to 100, and the entry beside it uses 20 and 80 for the same job. The numbers coincide. The meaning does not.
So when this page cites a detector it will be batch_zigzag, and the claim will be about swings, never about levels. That distinction is the only thing that makes the rest of the page worth reading.
Where the two prices come from
The levels are trivial. Choosing p0 and p1 is the entire problem, and it is a problem our engine does have opinions about.
structure.rs ships four kernels and two of them find swings. batch_zigzag (structure.rs:100) walks forward tracking a running extreme, and when price counter-moves by at least deviation percent it writes that extreme back at its own bar and reverses direction. batch_williams_fractal (structure.rs:158) is simpler: a bar is a fractal high when its high is strictly above the two bars either side.
Both are reached through the Zigzag and WilliamsFractal structs — the kernels themselves are private to the module, so "the crate exposes batch_zigzag" would be wrong. What you get back is a price at a pivot bar and nothing between.
Across 299 pairs and 364,147 daily bars, batch_zigzag at its registered 5.0% deviation produced 150,839 swings. Each one is a candidate anchor pair, and the lag before you may use one is small: the median pivot became knowable one bar after it printed.
Move the anchor and the level moves with it
Here is the measurement that changed how I look at these lines.
deviation is a parameter with a registered default of 5.0 and a legal range from 0.1 to 50. Run the same bars at 3, 5 and 10 and you get three different sets of swings, so at any given bar there are three different "last completed swing" answers and therefore three different 61.8% levels.
Computing all three on every bar of the daily tape puts a size on that choice. The spread between them had a median of 2.48% of price, and 13.22% at the ninetieth percentile. Worse than the width: on 88,023 of 360,804 bars — 24.4% — the three settings disagreed about where price had closed relative to the 61.8% line.
That is a quarter of all bars where "the golden pocket held" and "the golden pocket broke" are both defensible, from the same data, using the same tool, differing only in a number somebody typed into a settings box. No amount of care with the drawing hand fixes that, because the drawing hand is not where the choice lives.
Where real retracements actually land
Since the engine finds the swings, it can also say where price came back to on real tape rather than in an illustration.
Taking every three-pivot sequence — a leg, then the pullback that ended it — gives 141,501 measured retracements. The median came back 90.3% of the leg. A quarter went past 138.5%. Only 18.8% of them stopped inside the 0.382 to 0.618 band, and 43.4% of them retraced past the leg's own origin, which means they were not retracements at all but reversals wearing the name until you looked.
Restrict to the legs that did stay under 100% and the picture improves: 33.1% of those landed in the golden pocket, against a band that occupies 23.6% of the available range. Real, and about 1.4 times what an even spread would give.
Now the caveat that matters more than the number. batch_zigzag ends a leg only after price has moved 5% against it, so a two percent pullback is invisible to this measurement by construction. The empty left edge of that distribution is the detector's threshold, not a fact about markets. Any histogram of retracement depth is partly a picture of the tool that cut it up, and I have not seen that stated on a page that publishes one.
Where the levels miss
Two real swings where the retracement stopped almost exactly on a line, and two where it went through every one of them without pausing.
Both are here because the first pair is what every article about this tool is made of, and the second pair is the reason the first pair proves nothing on its own. When a level is hit within a few hundredths of a percent it looks like physics. When I've watched the same drawing get ignored completely, the chart was not doing anything different — I was.
The practical habit I have settled on is narrow: I use a swing the engine confirmed, I keep the deviation fixed rather than tuning it after the fact, and I treat a level as a place to have a plan rather than a reason to have a position. Pivot points and the volume profile point of control are both levels our engine genuinely computes, from rules that cannot be adjusted after the outcome is known, and that property is worth more than the mystique.
Frequently asked questions
Is fibonacci retracement reliable? It is arithmetic, so it is perfectly reproducible once the two anchor prices are fixed. Fixing them is the hard part: three reasonable settings of one parameter reached opposite verdicts on 24.4% of bars.
What is the golden pocket? The band between the 0.382 and 0.618 levels. Of the real retracements that stayed under 100% of their leg, 33.1% ended inside it, against a band width of 23.6%.
Which swing should I use?
Whichever one you can define without seeing the answer first. Our engine's own answer is a batch_zigzag pivot at a deviation you fixed in advance, which at least removes the temptation to pick the swing that makes the level land where you want it.
Does the engine draw fibonacci levels?
No. There is no fibonacci function anywhere in crates/vike-indicators. It ships the swing finders and stops there, and this page is the honest version of that answer rather than a marketing one.
How is this different from a candlestick signal? A candlestick pattern is decided by one bar's own four prices and cannot be moved by a setting. A retracement level is decided by two prices you chose, which is a much softer kind of fact.
This is educational material, not financial advice. Every figure here was measured on past bars, past behavior generalizes poorly to future bars, and trading carries real risk of loss — size any position so that being wrong stays survivable.