Skip to content

turtle_quant_1.strategies.helpers.support_resistance.stnry_local_extrema

turtle_quant_1.strategies.helpers.support_resistance.stnry_local_extrema

Stationary local extrema static support and resistance strategy.

StnryLocalExtrema

StnryLocalExtrema(
    strong_peak_distance: int = 10,
    strong_peak_prominence_pct: float = 0.01,
    peak_distance: int = 5,
    peak_rank_width: float = 2.0,
    res_min_pivot_rank: int = 3,
)

Bases: BaseSupResStrategy

Stationary local extrema static support and resistance strategy.

Refer to https://medium.com/@itay1542/how-to-calculate-support-and-resistance-levels-using-python-a-step-by-step-guide-e94a33c6cbda.

This strategy identifies support and resistance levels by finding local extrema (peaks and troughs) in the price data and ranking them based on their frequency and proximity to other extrema.

Initialize the StnryLocalExtrema strategy.

Parameters:

Name Type Description Default
strong_peak_distance int

Distance between strong peaks (in days).

10
strong_peak_prominence_pct float

Prominence for strong peaks (as fraction of price range).

0.01
peak_distance int

Distance between general peaks (in days).

5
peak_rank_width float

Width for grouping nearby peaks.

2.0
res_min_pivot_rank int

Minimum rank for resistance levels.

3
Source code in src/turtle_quant_1/strategies/helpers/support_resistance/stnry_local_extrema.py
def __init__(
    self,
    strong_peak_distance: int = 10,
    strong_peak_prominence_pct: float = 0.01,
    peak_distance: int = 5,
    peak_rank_width: float = 2.0,
    res_min_pivot_rank: int = 3,
):
    """Initialize the StnryLocalExtrema strategy.

    Args:
        strong_peak_distance: Distance between strong peaks (in days).
        strong_peak_prominence_pct: Prominence for strong peaks (as fraction of price range).
        peak_distance: Distance between general peaks (in days).
        peak_rank_width: Width for grouping nearby peaks.
        res_min_pivot_rank: Minimum rank for resistance levels.
    """
    super().__init__()

    self.sup_res_zone_threshold = 0.01  # Within 2% of the level

    self.strong_peak_distance = strong_peak_distance
    self.strong_peak_prominence_pct = strong_peak_prominence_pct
    self.peak_distance = peak_distance
    self.peak_rank_width = peak_rank_width
    self.res_min_pivot_rank = res_min_pivot_rank

generate_historical_levels

generate_historical_levels(
    data: DataFrame, symbol: str
) -> DataFrame

Generate all support and resistance levels for historical data.

Parameters:

Name Type Description Default
data DataFrame

DataFrame with OHLCV data containing columns: ['datetime', 'Open', 'High', 'Low', 'Close', 'Volume']

required
symbol str

The symbol being analyzed.

required

Returns:

Type Description
DataFrame

DataFrame with support and resistance levels.

DataFrame

The columns are: ['datetime', 'level_values'].

Source code in src/turtle_quant_1/strategies/helpers/support_resistance/stnry_local_extrema.py
def generate_historical_levels(
    self, data: pd.DataFrame, symbol: str
) -> pd.DataFrame:
    """Generate all support and resistance levels for historical data.

    Args:
        data: DataFrame with OHLCV data containing columns:
              ['datetime', 'Open', 'High', 'Low', 'Close', 'Volume']
        symbol: The symbol being analyzed.

    Returns:
        DataFrame with support and resistance levels.
        The columns are: ['datetime', 'level_values'].
    """
    # Ensure we have the required columns
    if not all(col in data.columns for col in ["High", "Low"]):
        raise ValueError("Data must contain 'High' and 'Low' columns")

    level_values = self._calc_sup_res_levels(data)

    # Create output DataFrame with 1-to-1 mapping to original data
    result = pd.DataFrame(
        {
            "datetime": pd.to_datetime(data["datetime"]).reset_index(drop=True),
            "level_values": level_values,
        }
    )

    return result