Fibonacci retracement is trivial arithmetic — the hard part is choosing the swing, which is exactly where subjectivity sneaks in (see the explainer). So in Python we’ll do both: compute the levels, and automate the swing selection so the whole thing becomes testable.
What you’ll need
- Python 3.9+,
pandas/numpy - A
close(or high/low) series.
The levels
def fib_levels(swing_high: float, swing_low: float) -> dict:
diff = swing_high - swing_low
ratios = {"0%": 0.0, "23.6%": 0.236, "38.2%": 0.382,
"50%": 0.5, "61.8%": 0.618, "78.6%": 0.786, "100%": 1.0}
# Measured up from the low (retracement of a down-move).
return {label: swing_low + r * diff for label, r in ratios.items()}
That’s the whole calculation: each level is low + ratio × (high − low). Swap the
measurement direction for retracing an up-move.
Auto-detecting the swing (making it mechanical)
The antidote to cherry-picking swings is to define them by rule — e.g. the highest high and lowest low over a lookback window:
def auto_fib(high, low, lookback: int = 90):
window_high = high.iloc[-lookback:]
window_low = low.iloc[-lookback:]
hi_idx = window_high.idxmax()
lo_idx = window_low.idxmin()
swing_high = window_high.max()
swing_low = window_low.min()
# Direction matters: was the high or the low more recent?
down_move = hi_idx < lo_idx
return fib_levels(swing_high, swing_low), down_move
Now the levels come from a repeatable rule, not your mood — which means you can actually backtest whether they hold in AlgoGen.
Testing whether a level holds
levels, _ = auto_fib(df["high"], df["low"])
golden_low, golden_high = levels["38.2%"], levels["61.8%"]
in_golden_zone = df["close"].between(golden_low, golden_high)
in_golden_zone flags bars trading in the 38.2–61.8% region — the spot to watch
for a reversal, and a concrete thing to measure.
Gotchas
- The swing choice is everything. Two different swings give two different level sets. Automate it so results are reproducible and honest.
- Direction. Retracing a down-move measures up from the low; an up-move measures down from the high. Track which one you’re in.
- 50% isn’t Fibonacci. It’s included by convention (Dow Theory), not derived from the sequence — keep it if you like, but know what it is.
The lazy way
There’s no universal fib library call because the swing is user-chosen, but with
auto-detected swings the function above is the implementation. Many charting
libraries expose a manual Fibonacci drawing tool instead.
Same indicator elsewhere: MQL5, Pine Script, EasyLanguage, NinjaScript.
This post is educational, not financial advice. Indicators describe the past; they don’t predict the future. Backtest anything before you risk real money on it.
Sources and further reading
- Windowing operations (pandas documentation)
