Pivot points and Fibonacci levels
Both are pre-computed support/resistance levels derived from prior price action — widely watched by enough intraday participants (especially in Indian index F&O) that they can become somewhat self-fulfilling.
Classic (Standard) Pivot Points — from the prior session's H/L/C
def classic_pivots(prev_high: float, prev_low: float, prev_close: float) -> dict:
pivot = (prev_high + prev_low + prev_close) / 3
r1 = 2 * pivot - prev_low
s1 = 2 * pivot - prev_high
r2 = pivot + (prev_high - prev_low)
s2 = pivot - (prev_high - prev_low)
r3 = prev_high + 2 * (pivot - prev_low)
s3 = prev_low - 2 * (prev_high - pivot)
return {"pivot": pivot, "r1": r1, "r2": r2, "r3": r3, "s1": s1, "s2": s2, "s3": s3}
Camarilla Pivots — tighter bands, popular for intraday reversal trading
def camarilla_pivots(prev_high: float, prev_low: float, prev_close: float) -> dict:
rng = prev_high - prev_low
return {
"r1": prev_close + rng * 1.1/12, "r2": prev_close + rng * 1.1/6,
"r3": prev_close + rng * 1.1/4, "r4": prev_close + rng * 1.1/2,
"s1": prev_close - rng * 1.1/12, "s2": prev_close - rng * 1.1/6,
"s3": prev_close - rng * 1.1/4, "s4": prev_close - rng * 1.1/2,
}
Camarilla's R3/S3 (and R4/S4 as breakout confirmation levels) are specifically popular among Indian intraday index-options traders for range-bound day setups — a common pattern: fade R3/S3 as reversal levels, treat a break of R4/S4 as a trend-day breakout signal instead.
Fibonacci Retracement — from a defined swing high/low
def fibonacci_retracement(swing_high: float, swing_low: float) -> dict:
diff = swing_high - swing_low
levels = [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1.0]
return {f"fib_{lvl}": swing_high - diff * lvl for lvl in levels}
Fibonacci Extension — projecting beyond the original swing, for targets
def fibonacci_extension(swing_high: float, swing_low: float, retracement_point: float) -> dict:
diff = swing_high - swing_low
levels = [1.272, 1.618, 2.0, 2.618]
return {f"ext_{lvl}": retracement_point + diff * lvl for lvl in levels}
The honest caveat on Fibonacci levels
Unlike pivot points (which are a pure, unambiguous arithmetic function of prior H/L/C), Fibonacci retracement requires *subjectively* choosing which swing high and swing low to measure from — two traders can draw completely different Fibonacci grids on the same chart. This subjectivity makes it far harder to backtest rigorously (chapter 82) or defend as a mechanical, reproducible signal — treat it as a discretionary tool for human chart reading rather than a candidate for an automated strategy unless you can define swing-point selection as an unambiguous algorithm first (e.g. a specific fractal/zigzag detection rule) and then validate that specific rule's results.
Automating swing-point selection, if you want Fibonacci in a bot
def find_swing_points(df: pd.DataFrame, order: int = 5) -> pd.DataFrame:
"""order: bars on each side that must be lower/higher for a point to count as a swing."""
from scipy.signal import argrelextrema
highs_idx = argrelextrema(df["high"].values, lambda a, b: a >= b, order=order)[0]
lows_idx = argrelextrema(df["low"].values, lambda a, b: a <= b, order=order)[0]
swings = pd.DataFrame(index=df.index)
swings["swing_high"] = df["high"].iloc[highs_idx]
swings["swing_low"] = df["low"].iloc[lows_idx]
return swings
This makes swing selection mechanical and reproducible — a prerequisite for treating any Fibonacci-based signal as backtestable rather than purely discretionary.