Skip to content

Pivot Detection

pivots

Pivot extraction utilities (EMA-derivative based).

Public API

ema_derivative_pivots(df: pd.DataFrame, ...) -> dict

Returns pivot indices for price & RSI along with metadata.

ema_derivative_pivots(df, price_col='Close', rsi_col='RSI', price_span=5, rsi_span=5)

Detect pivot highs/lows via sign changes in first derivative of EMA-smoothed series.

Method
  1. Smooth price & RSI with EMA.
  2. Compute first difference (derivative).
  3. Identify sign-change points as pivots:
    • Pivot Low: derivative < 0 then > 0.
    • Pivot High: derivative > 0 then < 0.

Parameters:

Name Type Description Default
df DataFrame

DataFrame containing at least price_col and rsi_col.

required
price_col str

Price column name (default "Close").

'Close'
rsi_col str

RSI column name (default "RSI").

'RSI'
price_span int

EMA span for price smoothing.

5
rsi_span int

EMA span for RSI smoothing.

5

Returns:

Type Description
dict[str, Any]

Dict with keys: price_highs, price_lows, rsi_highs, rsi_lows, meta.

dict[str, Any]

meta includes method name and counts.

Source code in src/stockcharts/indicators/pivots.py
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
def ema_derivative_pivots(
    df: pd.DataFrame,
    price_col: str = "Close",
    rsi_col: str = "RSI",
    price_span: int = 5,
    rsi_span: int = 5,
) -> dict[str, Any]:
    """Detect pivot highs/lows via sign changes in first derivative of EMA-smoothed series.

    Method:
        1. Smooth price & RSI with EMA.
        2. Compute first difference (derivative).
        3. Identify sign-change points as pivots:
            - Pivot Low: derivative < 0 then > 0.
            - Pivot High: derivative > 0 then < 0.

    Args:
        df: DataFrame containing at least ``price_col`` and ``rsi_col``.
        price_col: Price column name (default "Close").
        rsi_col: RSI column name (default "RSI").
        price_span: EMA span for price smoothing.
        rsi_span: EMA span for RSI smoothing.

    Returns:
        Dict with keys: ``price_highs``, ``price_lows``, ``rsi_highs``, ``rsi_lows``, ``meta``.
        ``meta`` includes method name and counts.
    """
    if price_col not in df.columns or rsi_col not in df.columns:
        return {
            "price_highs": pd.Index([]),
            "price_lows": pd.Index([]),
            "rsi_highs": pd.Index([]),
            "rsi_lows": pd.Index([]),
            "meta": {"method": "ema-deriv", "error": "Missing required columns"},
        }

    price_smoothed = _ema(df[price_col], price_span)
    rsi_smoothed = _ema(df[rsi_col], rsi_span)

    price_derivative = price_smoothed.diff()
    rsi_derivative = rsi_smoothed.diff()

    price_lows = price_smoothed[(price_derivative.shift(1) < 0) & (price_derivative > 0)].index
    price_highs = price_smoothed[(price_derivative.shift(1) > 0) & (price_derivative < 0)].index
    rsi_lows = rsi_smoothed[(rsi_derivative.shift(1) < 0) & (rsi_derivative > 0)].index
    rsi_highs = rsi_smoothed[(rsi_derivative.shift(1) > 0) & (rsi_derivative < 0)].index

    return {
        "price_highs": price_highs,
        "price_lows": price_lows,
        "rsi_highs": rsi_highs,
        "rsi_lows": rsi_lows,
        "meta": {
            "method": "ema-deriv",
            "price_span": price_span,
            "rsi_span": rsi_span,
            "price_pivots": len(price_highs) + len(price_lows),
            "rsi_pivots": len(rsi_highs) + len(rsi_lows),
        },
    }

EMA-Derivative Method (Merged Guide)

Replaces earlier ZigZag approach for cleaner, parameter-light pivot extraction.

Logic

  1. Smooth series with EMA (price & RSI).
  2. Compute first derivative (rate of change).
  3. Sign change identifies pivot (negative→positive = low, positive→negative = high).

Advantages

  • Minimal parameters (span only).
  • Robust against noise.
  • Symmetric application to price & RSI.
  • Linear complexity.

Span Selection

Span Sensitivity Use Case
3-4 High Intraday/fast scans
5-6 Balanced Swing trading (default)
7-9 Smooth Position trading
10+ Very Smooth Major turns only

CLI Flags

--pivot-method ema-deriv --ema-price-span N --ema-rsi-span N

Example

stockcharts-rsi-divergence --type bullish --pivot-method ema-deriv --ema-price-span 7 --ema-rsi-span 7

Future Enhancements

Adaptive spans, derivative thresholding, multi-span confirmation.