rsi-divergence-detector


Namersi-divergence-detector JSON
Version 0.1.0 PyPI version JSON
download
home_pageNone
SummaryA tool to detect RSI divergences in price data.
upload_time2025-08-11 16:23:55
maintainerNone
docs_urlNone
authorTomi Šeregi
requires_python<3.14,>=3.9
licenseBSD-3-Clause
keywords rsi divergence finance trading technical-analysis
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # rsi-divergence-detector

**Lightweight, tested Python library & CLI for detecting RSI divergences (regular & hidden) on time‑series price data.**

It uses **Wilder‑style RSI**, **robust peak finding** via SciPy, and **deterministic, monotonic pivot pairing** with adaptive defaults so you can get useful results with minimal tuning. Clean function contracts, no hidden globals, and a tidy tabular output.

> **Python**: 3.9–3.13 · **Dependencies**: NumPy (>=1.26), pandas (>=2.2.2), SciPy (>=1.13), Typer (for the CLI)

---

## Table of Contents

* [Features](#features)
* [Install](#install)
* [Quickstart (Python API)](#quickstart-python-api)
* [Quickstart (CLI)](#quickstart-cli)
* [Returned Schema](#returned-schema)
* [Concepts & Algorithm](#concepts--algorithm)

  * [Divergences we detect](#divergences-we-detect)
  * [RSI (Wilder‑style)](#rsi-wilderstyle)
  * [Peak detection (SciPy)](#peak-detection-scipy)
  * [Monotonic pivot pairing](#monotonic-pivot-pairing)
* [API Reference](#api-reference)

  * [`calculate_rsi`](#calculate_rsi)
  * [`find_divergences`](#find_divergences)
* [Tuning Tips](#tuning-tips)
* [Examples](#examples)
* [Testing](#testing)
* [Versioning / Compatibility](#versioning--compatibility)
* [Limitations & Notes](#limitations--notes)
* [Roadmap](#roadmap)
* [License](#license)
* [References](#references)
* [SEO Keywords](#seo-keywords)

---

## Features

* ✅ **Regular & hidden RSI divergences**: `regular_bullish`, `regular_bearish`, `hidden_bullish`, `hidden_bearish`.
* ✅ **Deterministic pairing**: nearest‑in‑time RSI pivots for each consecutive price pivot pair; **monotonic in time** (no re‑use/backtracking).
* ✅ **Adaptive defaults** for peak gates (prominence/width/distance) to stay scale‑aware without hand‑tuning.
* ✅ **Clear contracts**: explicit, stateless functions returning a tidy DataFrame.
* ✅ **CLI + Python API** (Typer‑powered CLI with `--help`).
* ✅ **Tests**: unit tests (RSI consistency & divergence scenarios) + property tests (Hypothesis) + CLI smoke tests.

---

## Install

From PyPI:

```bash
pip install rsi-divergence-detector
```

> Uses prebuilt wheels for NumPy/SciPy on common platforms; keep Python/pip recent for smooth installs.

---

## Quickstart (Python API)

```python
import pandas as pd
from rsi_divergence import calculate_rsi, find_divergences

# Price series with DatetimeIndex
close = pd.read_csv("ohlc.csv", index_col=0, parse_dates=True)["close"]

# Wilder-style RSI (period=14)
rsi = calculate_rsi(close, period=14)

# Detect divergences using adaptive defaults
divs = find_divergences(
    prices=close,
    rsi=rsi,
    rsi_period=14,       # used for adaptive defaults
    max_lag=3,           # bars allowed between paired price/RSI pivots
    include_hidden=True, # include hidden (continuation) divergences
)

print(divs.head())
```

---

## Quickstart (CLI)

Read a CSV with a `close` column (index = timestamps):

```bash
rsi_divergence --file ohlc.csv --rsi-period 14
```

Optional tuning (omit to use adaptive defaults):

```bash
rsi_divergence \
  --file ohlc.csv \
  --rsi-period 14 \
  --price-prominence 0.25 \
  --rsi-prominence 5 \
  --price-width 2 \
  --rsi-width 2 \
  --distance 7 \
  --max-lag 3 \
  --include-hidden
```

> The CLI is built with **Typer**; `--help` shows all options and help text.

---

## Returned Schema

The detector returns a `pd.DataFrame` with one row per divergence:

```
['kind','p1_idx','p1_price','p2_idx','p2_price','r1_idx','r1_val','r2_idx','r2_val']
```

* `kind`: one of `regular_bullish`, `regular_bearish`, `hidden_bullish`, `hidden_bearish`
* `p1_idx`, `p2_idx`: timestamps of the price pivots (first → second)
* `p1_price`, `p2_price`: price at those pivots
* `r1_idx`, `r2_idx`: timestamps of the paired RSI pivots
* `r1_val`, `r2_val`: RSI values at those pivots

---

## Concepts & Algorithm

### Divergences we detect

* **Regular bullish**: price makes **lower low (LL)**, RSI makes **higher low (HL)** → potential reversal up.
* **Regular bearish**: price makes **higher high (HH)**, RSI makes **lower high (LH)** → potential reversal down.
* **Hidden bullish**: price **HL**, RSI **LL** → continuation of **uptrend**.
* **Hidden bearish**: price **LH**, RSI **HH** → continuation of **downtrend**.

> Hidden divergences are commonly framed as **trend continuation**; regular divergences as **reversal‑leaning**.

### RSI (Wilder‑style)

We compute RSI exactly as described by Wilder: average gains/losses smoothed with **Wilder’s smoothing** (a form of exponential smoothing with $\alpha = 1/\text{period}$), then
$\text{RSI} = 100 - \frac{100}{1+RS} \quad \text{where} \quad RS = \frac{\text{avg gain}}{\text{avg loss}}.$
The output is aligned to the input index and lives in **\[0, 100]** (initial warm‑up may contain NaNs).

### Peak detection (SciPy)

We locate local extrema on **price** and **RSI** using `scipy.signal.find_peaks`. Minima are obtained by applying `find_peaks` to the **negated series**. The following gates control selection:

* **prominence** — how much a peak stands out relative to its surroundings
* **width** — peak “thickness” in samples
* **distance** — minimum separation between neighboring peaks

**Adaptive defaults** (used when the parameter is `None`):

* `price_prominence` ≈ `0.5 * rolling_std(pct_change, window=rsi_period).iloc[-1] * last_price` (scale‑aware)
* `rsi_prominence` = `5.0` (RSI points)
* `price_width` = `2`, `rsi_width` = `2`
* `distance` = `max(1, rsi_period // 2)`

### Monotonic pivot pairing

For each **consecutive price pivot pair** (minima for bullish paths, maxima for bearish), we pick the **nearest‑in‑time RSI pivots** within ±`max_lag` bars. Pairing is **monotonic**: the second RSI pivot must occur **after** the first RSI pivot used in that loop, and we don’t re‑use RSI pivots out of order. When comparisons below hold, we append a row:

* `regular_bullish`: `price2 < price1` **and** `rsi2 > rsi1`
* `regular_bearish`: `price2 > price1` **and** `rsi2 < rsi1`
* `hidden_bullish`: `price2 > price1` **and** `rsi2 < rsi1`
* `hidden_bearish`: `price2 < price1` **and** `rsi2 > rsi1`

`allow_equal=True` (default) makes comparisons inclusive (tolerant to ties on intrabar data).

---

## API Reference

### `calculate_rsi`

```python
calculate_rsi(prices: pd.Series, period: int = 14) -> pd.Series
```

**Contract**

* `prices`: non‑empty `pd.Series` with a **monotonic increasing `DatetimeIndex`**.
* Returns an RSI `pd.Series` aligned to `prices.index` with values in **\[0,100]** (warm‑up may contain NaNs).
* Implements **Wilder‑style** smoothing (equivalent to an EMA with `alpha = 1/period`, `adjust=False`).

### `find_divergences`

```python
find_divergences(
    prices: pd.Series,
    rsi: pd.Series,
    *,
    rsi_period: int = 14,
    price_prominence: float | None = None,
    rsi_prominence: float | None = None,
    price_width: int | None = None,
    rsi_width: int | None = None,
    distance: int | None = None,
    max_lag: int = 3,
    include_hidden: bool = True,
    allow_equal: bool = True,
) -> pd.DataFrame
```

**Inputs**

* `prices`, `rsi`: numeric `pd.Series` with the **same `DatetimeIndex`** (RSI will be reindexed to `prices`).
* `rsi` can have initial NaNs (warm‑up).
* **Adaptive defaults** apply when gates are `None` (see above).

**Pairing & rules**

* For each consecutive price pivot pair, find nearest RSI pivots within ±`max_lag` bars, enforcing **monotonic time**.
* Append a row when the rule for the target divergence holds (see [Monotonic pivot pairing](#monotonic-pivot-pairing)).

**Returns**

* A tidy `pd.DataFrame` with the [columns described here](#returned-schema).

---

## Tuning Tips

* Too **few** pivots? Lower `price_prominence` / `rsi_prominence` and/or `distance`, or increase `max_lag`.
* Too **many/weak** pivots? Increase **prominence** and **width**.
* Intraday noise: increase `width` and `distance` to suppress micro‑wiggles.
* Interested in classical RSI zones (≈30/70)? Filter results post‑hoc by `r1_val`/`r2_val` ranges. (Heuristics, not hard rules.)

---

## Examples

**Minimal flow**

```python
import pandas as pd
from rsi_divergence import calculate_rsi, find_divergences

close = pd.read_csv("ohlc.csv", index_col=0, parse_dates=True)["close"]
rsi = calculate_rsi(close, period=14)
divs = find_divergences(close, rsi, rsi_period=14, include_hidden=True)
print(divs.tail())
```

**Filtering for “strong” bearish signals**

```python
strong = divs[(divs["kind"].str.contains("bearish")) & (divs["r2_val"] > 65.0)]
```

**Plotting (optional)**
Layer `p1/p2` and `r1/r2` pivots over candles (e.g., with `mplfinance`) to visualize each divergence. Plotting is intentionally **out‑of‑scope** here to keep the core lightweight.

---

## Testing

We ship unit tests and property tests:

* **Unit tests**: RSI contract, range, Wilder consistency; deterministic divergence scenarios; CLI smoke test.
* **Property tests** (Hypothesis): generator‑driven random but valid series; **no crashes**, **stable schema**.

Run the suite:

```bash
pip install -r requirements-dev.txt  # or: pip install -e ".[dev]"
pytest -q
```

---

## Versioning / Compatibility

* **Python**: 3.9–3.13
* **NumPy**: ≥ 1.26 (works with NumPy 2.x)
* **pandas**: ≥ 2.2.2
* **SciPy**: ≥ 1.13

We avoid strict upper pins to reduce resolver conflicts across environments.

---

## Limitations & Notes

* Divergences can **persist** without immediate reversal/continuation; confirm with broader structure/flow.
* Peak‑based methods are **parameter‑sensitive**; adaptive defaults help, but **context matters** (market, timeframe).
* This library **does not** predict or place orders; it **annotates structure** to support your own analysis.

---

## Roadmap

A forward‑looking sketch (subject to change):

* Optional **zone‑aware scoring** (down‑weight signals far from RSI 30/70 bands).
* **Multi‑timeframe** aggregation (e.g., 1h pivots confirming 5m signals).
* **Volume/OI/CVD** hooks for richer filters.
* **Numba/JIT** fast‑path for large universes.
* Streaming examples (WebSocket → rolling detection).

PRs welcome!

---

## References

* **RSI (Wilder)** and smoothing background — StockCharts “RSI” notes; TC2000 help; Wikipedia overview.

  * StockCharts: [https://chartschool.stockcharts.com/table-of-contents/technical-indicators-and-overlays/technical-indicators/relative-strength-index-rsi](https://chartschool.stockcharts.com/table-of-contents/technical-indicators-and-overlays/technical-indicators/relative-strength-index-rsi)
  * TC2000 Help: [https://help.tc2000.com/m/69404/l/747071-rsi-wilder-s-rsi](https://help.tc2000.com/m/69404/l/747071-rsi-wilder-s-rsi)
  * Wikipedia: [https://en.wikipedia.org/wiki/Relative\_strength\_index](https://en.wikipedia.org/wiki/Relative_strength_index)
* **Divergence** (regular vs hidden) — Babypips primers; Investopedia overviews.

  * Babypips Hidden Divergence: [https://www.babypips.com/learn/forex/hidden-divergence](https://www.babypips.com/learn/forex/hidden-divergence)
  * Babypips Divergence Cheatsheet: [https://www.babypips.com/learn/forex/divergence-cheat-sheet](https://www.babypips.com/learn/forex/divergence-cheat-sheet)
  * Investopedia Divergence: [https://www.investopedia.com/terms/d/divergence.asp](https://www.investopedia.com/terms/d/divergence.asp)
* **SciPy peak selection** — `find_peaks`, `peak_prominences`, `peak_widths`.

  * find\_peaks: [https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find\_peaks.html](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html)
  * peak\_prominences: [https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.peak\_prominences.html](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.peak_prominences.html)
  * peak\_widths: [https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.peak\_widths.html](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.peak_widths.html)
* **Typer (CLI)** — official docs.

  * Typer: [https://typer.tiangolo.com/](https://typer.tiangolo.com/)

---

## SEO Keywords

RSI divergence detector, RSI hidden divergence, Wilder RSI Python, RSI Wilder smoothing, RSI divergence Python library, SciPy find_peaks RSI, RSI divergence CLI, regular vs hidden divergence, price oscillator divergence, RSI 30/70 heuristic, pandas RSI, quantitative trading divergence, Python technical analysis.


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "rsi-divergence-detector",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<3.14,>=3.9",
    "maintainer_email": null,
    "keywords": "rsi, divergence, finance, trading, technical-analysis",
    "author": "Tomi \u0160eregi",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/b1/c5/a8f65a79464b213adfc32d134d549a03b9b8b624e0bc34c48fe6473f5878/rsi_divergence_detector-0.1.0.tar.gz",
    "platform": null,
    "description": "# rsi-divergence-detector\n\n**Lightweight, tested Python library & CLI for detecting RSI divergences (regular & hidden) on time\u2011series price data.**\n\nIt uses **Wilder\u2011style RSI**, **robust peak finding** via SciPy, and **deterministic, monotonic pivot pairing** with adaptive defaults so you can get useful results with minimal tuning. Clean function contracts, no hidden globals, and a tidy tabular output.\n\n> **Python**: 3.9\u20133.13 \u00b7 **Dependencies**: NumPy (>=1.26), pandas (>=2.2.2), SciPy (>=1.13), Typer (for the CLI)\n\n---\n\n## Table of Contents\n\n* [Features](#features)\n* [Install](#install)\n* [Quickstart (Python API)](#quickstart-python-api)\n* [Quickstart (CLI)](#quickstart-cli)\n* [Returned Schema](#returned-schema)\n* [Concepts & Algorithm](#concepts--algorithm)\n\n  * [Divergences we detect](#divergences-we-detect)\n  * [RSI (Wilder\u2011style)](#rsi-wilderstyle)\n  * [Peak detection (SciPy)](#peak-detection-scipy)\n  * [Monotonic pivot pairing](#monotonic-pivot-pairing)\n* [API Reference](#api-reference)\n\n  * [`calculate_rsi`](#calculate_rsi)\n  * [`find_divergences`](#find_divergences)\n* [Tuning Tips](#tuning-tips)\n* [Examples](#examples)\n* [Testing](#testing)\n* [Versioning / Compatibility](#versioning--compatibility)\n* [Limitations & Notes](#limitations--notes)\n* [Roadmap](#roadmap)\n* [License](#license)\n* [References](#references)\n* [SEO Keywords](#seo-keywords)\n\n---\n\n## Features\n\n* \u2705 **Regular & hidden RSI divergences**: `regular_bullish`, `regular_bearish`, `hidden_bullish`, `hidden_bearish`.\n* \u2705 **Deterministic pairing**: nearest\u2011in\u2011time RSI pivots for each consecutive price pivot pair; **monotonic in time** (no re\u2011use/backtracking).\n* \u2705 **Adaptive defaults** for peak gates (prominence/width/distance) to stay scale\u2011aware without hand\u2011tuning.\n* \u2705 **Clear contracts**: explicit, stateless functions returning a tidy DataFrame.\n* \u2705 **CLI + Python API** (Typer\u2011powered CLI with `--help`).\n* \u2705 **Tests**: unit tests (RSI consistency & divergence scenarios) + property tests (Hypothesis) + CLI smoke tests.\n\n---\n\n## Install\n\nFrom PyPI:\n\n```bash\npip install rsi-divergence-detector\n```\n\n> Uses prebuilt wheels for NumPy/SciPy on common platforms; keep Python/pip recent for smooth installs.\n\n---\n\n## Quickstart (Python API)\n\n```python\nimport pandas as pd\nfrom rsi_divergence import calculate_rsi, find_divergences\n\n# Price series with DatetimeIndex\nclose = pd.read_csv(\"ohlc.csv\", index_col=0, parse_dates=True)[\"close\"]\n\n# Wilder-style RSI (period=14)\nrsi = calculate_rsi(close, period=14)\n\n# Detect divergences using adaptive defaults\ndivs = find_divergences(\n    prices=close,\n    rsi=rsi,\n    rsi_period=14,       # used for adaptive defaults\n    max_lag=3,           # bars allowed between paired price/RSI pivots\n    include_hidden=True, # include hidden (continuation) divergences\n)\n\nprint(divs.head())\n```\n\n---\n\n## Quickstart (CLI)\n\nRead a CSV with a `close` column (index = timestamps):\n\n```bash\nrsi_divergence --file ohlc.csv --rsi-period 14\n```\n\nOptional tuning (omit to use adaptive defaults):\n\n```bash\nrsi_divergence \\\n  --file ohlc.csv \\\n  --rsi-period 14 \\\n  --price-prominence 0.25 \\\n  --rsi-prominence 5 \\\n  --price-width 2 \\\n  --rsi-width 2 \\\n  --distance 7 \\\n  --max-lag 3 \\\n  --include-hidden\n```\n\n> The CLI is built with **Typer**; `--help` shows all options and help text.\n\n---\n\n## Returned Schema\n\nThe detector returns a `pd.DataFrame` with one row per divergence:\n\n```\n['kind','p1_idx','p1_price','p2_idx','p2_price','r1_idx','r1_val','r2_idx','r2_val']\n```\n\n* `kind`: one of `regular_bullish`, `regular_bearish`, `hidden_bullish`, `hidden_bearish`\n* `p1_idx`, `p2_idx`: timestamps of the price pivots (first \u2192 second)\n* `p1_price`, `p2_price`: price at those pivots\n* `r1_idx`, `r2_idx`: timestamps of the paired RSI pivots\n* `r1_val`, `r2_val`: RSI values at those pivots\n\n---\n\n## Concepts & Algorithm\n\n### Divergences we detect\n\n* **Regular bullish**: price makes **lower low (LL)**, RSI makes **higher low (HL)** \u2192 potential reversal up.\n* **Regular bearish**: price makes **higher high (HH)**, RSI makes **lower high (LH)** \u2192 potential reversal down.\n* **Hidden bullish**: price **HL**, RSI **LL** \u2192 continuation of **uptrend**.\n* **Hidden bearish**: price **LH**, RSI **HH** \u2192 continuation of **downtrend**.\n\n> Hidden divergences are commonly framed as **trend continuation**; regular divergences as **reversal\u2011leaning**.\n\n### RSI (Wilder\u2011style)\n\nWe compute RSI exactly as described by Wilder: average gains/losses smoothed with **Wilder\u2019s smoothing** (a form of exponential smoothing with $\\alpha = 1/\\text{period}$), then\n$\\text{RSI} = 100 - \\frac{100}{1+RS} \\quad \\text{where} \\quad RS = \\frac{\\text{avg gain}}{\\text{avg loss}}.$\nThe output is aligned to the input index and lives in **\\[0, 100]** (initial warm\u2011up may contain NaNs).\n\n### Peak detection (SciPy)\n\nWe locate local extrema on **price** and **RSI** using `scipy.signal.find_peaks`. Minima are obtained by applying `find_peaks` to the **negated series**. The following gates control selection:\n\n* **prominence** \u2014 how much a peak stands out relative to its surroundings\n* **width** \u2014 peak \u201cthickness\u201d in samples\n* **distance** \u2014 minimum separation between neighboring peaks\n\n**Adaptive defaults** (used when the parameter is `None`):\n\n* `price_prominence` \u2248 `0.5 * rolling_std(pct_change, window=rsi_period).iloc[-1] * last_price` (scale\u2011aware)\n* `rsi_prominence` = `5.0` (RSI points)\n* `price_width` = `2`, `rsi_width` = `2`\n* `distance` = `max(1, rsi_period // 2)`\n\n### Monotonic pivot pairing\n\nFor each **consecutive price pivot pair** (minima for bullish paths, maxima for bearish), we pick the **nearest\u2011in\u2011time RSI pivots** within \u00b1`max_lag` bars. Pairing is **monotonic**: the second RSI pivot must occur **after** the first RSI pivot used in that loop, and we don\u2019t re\u2011use RSI pivots out of order. When comparisons below hold, we append a row:\n\n* `regular_bullish`: `price2 < price1` **and** `rsi2 > rsi1`\n* `regular_bearish`: `price2 > price1` **and** `rsi2 < rsi1`\n* `hidden_bullish`: `price2 > price1` **and** `rsi2 < rsi1`\n* `hidden_bearish`: `price2 < price1` **and** `rsi2 > rsi1`\n\n`allow_equal=True` (default) makes comparisons inclusive (tolerant to ties on intrabar data).\n\n---\n\n## API Reference\n\n### `calculate_rsi`\n\n```python\ncalculate_rsi(prices: pd.Series, period: int = 14) -> pd.Series\n```\n\n**Contract**\n\n* `prices`: non\u2011empty `pd.Series` with a **monotonic increasing `DatetimeIndex`**.\n* Returns an RSI `pd.Series` aligned to `prices.index` with values in **\\[0,100]** (warm\u2011up may contain NaNs).\n* Implements **Wilder\u2011style** smoothing (equivalent to an EMA with `alpha = 1/period`, `adjust=False`).\n\n### `find_divergences`\n\n```python\nfind_divergences(\n    prices: pd.Series,\n    rsi: pd.Series,\n    *,\n    rsi_period: int = 14,\n    price_prominence: float | None = None,\n    rsi_prominence: float | None = None,\n    price_width: int | None = None,\n    rsi_width: int | None = None,\n    distance: int | None = None,\n    max_lag: int = 3,\n    include_hidden: bool = True,\n    allow_equal: bool = True,\n) -> pd.DataFrame\n```\n\n**Inputs**\n\n* `prices`, `rsi`: numeric `pd.Series` with the **same `DatetimeIndex`** (RSI will be reindexed to `prices`).\n* `rsi` can have initial NaNs (warm\u2011up).\n* **Adaptive defaults** apply when gates are `None` (see above).\n\n**Pairing & rules**\n\n* For each consecutive price pivot pair, find nearest RSI pivots within \u00b1`max_lag` bars, enforcing **monotonic time**.\n* Append a row when the rule for the target divergence holds (see [Monotonic pivot pairing](#monotonic-pivot-pairing)).\n\n**Returns**\n\n* A tidy `pd.DataFrame` with the [columns described here](#returned-schema).\n\n---\n\n## Tuning Tips\n\n* Too **few** pivots? Lower `price_prominence` / `rsi_prominence` and/or `distance`, or increase `max_lag`.\n* Too **many/weak** pivots? Increase **prominence** and **width**.\n* Intraday noise: increase `width` and `distance` to suppress micro\u2011wiggles.\n* Interested in classical RSI zones (\u224830/70)? Filter results post\u2011hoc by `r1_val`/`r2_val` ranges. (Heuristics, not hard rules.)\n\n---\n\n## Examples\n\n**Minimal flow**\n\n```python\nimport pandas as pd\nfrom rsi_divergence import calculate_rsi, find_divergences\n\nclose = pd.read_csv(\"ohlc.csv\", index_col=0, parse_dates=True)[\"close\"]\nrsi = calculate_rsi(close, period=14)\ndivs = find_divergences(close, rsi, rsi_period=14, include_hidden=True)\nprint(divs.tail())\n```\n\n**Filtering for \u201cstrong\u201d bearish signals**\n\n```python\nstrong = divs[(divs[\"kind\"].str.contains(\"bearish\")) & (divs[\"r2_val\"] > 65.0)]\n```\n\n**Plotting (optional)**\nLayer `p1/p2` and `r1/r2` pivots over candles (e.g., with `mplfinance`) to visualize each divergence. Plotting is intentionally **out\u2011of\u2011scope** here to keep the core lightweight.\n\n---\n\n## Testing\n\nWe ship unit tests and property tests:\n\n* **Unit tests**: RSI contract, range, Wilder consistency; deterministic divergence scenarios; CLI smoke test.\n* **Property tests** (Hypothesis): generator\u2011driven random but valid series; **no crashes**, **stable schema**.\n\nRun the suite:\n\n```bash\npip install -r requirements-dev.txt  # or: pip install -e \".[dev]\"\npytest -q\n```\n\n---\n\n## Versioning / Compatibility\n\n* **Python**: 3.9\u20133.13\n* **NumPy**: \u2265 1.26 (works with NumPy 2.x)\n* **pandas**: \u2265 2.2.2\n* **SciPy**: \u2265 1.13\n\nWe avoid strict upper pins to reduce resolver conflicts across environments.\n\n---\n\n## Limitations & Notes\n\n* Divergences can **persist** without immediate reversal/continuation; confirm with broader structure/flow.\n* Peak\u2011based methods are **parameter\u2011sensitive**; adaptive defaults help, but **context matters** (market, timeframe).\n* This library **does not** predict or place orders; it **annotates structure** to support your own analysis.\n\n---\n\n## Roadmap\n\nA forward\u2011looking sketch (subject to change):\n\n* Optional **zone\u2011aware scoring** (down\u2011weight signals far from RSI 30/70 bands).\n* **Multi\u2011timeframe** aggregation (e.g., 1h pivots confirming 5m signals).\n* **Volume/OI/CVD** hooks for richer filters.\n* **Numba/JIT** fast\u2011path for large universes.\n* Streaming examples (WebSocket \u2192 rolling detection).\n\nPRs welcome!\n\n---\n\n## References\n\n* **RSI (Wilder)** and smoothing background \u2014 StockCharts \u201cRSI\u201d notes; TC2000 help; Wikipedia overview.\n\n  * StockCharts: [https://chartschool.stockcharts.com/table-of-contents/technical-indicators-and-overlays/technical-indicators/relative-strength-index-rsi](https://chartschool.stockcharts.com/table-of-contents/technical-indicators-and-overlays/technical-indicators/relative-strength-index-rsi)\n  * TC2000 Help: [https://help.tc2000.com/m/69404/l/747071-rsi-wilder-s-rsi](https://help.tc2000.com/m/69404/l/747071-rsi-wilder-s-rsi)\n  * Wikipedia: [https://en.wikipedia.org/wiki/Relative\\_strength\\_index](https://en.wikipedia.org/wiki/Relative_strength_index)\n* **Divergence** (regular vs hidden) \u2014 Babypips primers; Investopedia overviews.\n\n  * Babypips Hidden Divergence: [https://www.babypips.com/learn/forex/hidden-divergence](https://www.babypips.com/learn/forex/hidden-divergence)\n  * Babypips Divergence Cheatsheet: [https://www.babypips.com/learn/forex/divergence-cheat-sheet](https://www.babypips.com/learn/forex/divergence-cheat-sheet)\n  * Investopedia Divergence: [https://www.investopedia.com/terms/d/divergence.asp](https://www.investopedia.com/terms/d/divergence.asp)\n* **SciPy peak selection** \u2014 `find_peaks`, `peak_prominences`, `peak_widths`.\n\n  * find\\_peaks: [https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find\\_peaks.html](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html)\n  * peak\\_prominences: [https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.peak\\_prominences.html](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.peak_prominences.html)\n  * peak\\_widths: [https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.peak\\_widths.html](https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.peak_widths.html)\n* **Typer (CLI)** \u2014 official docs.\n\n  * Typer: [https://typer.tiangolo.com/](https://typer.tiangolo.com/)\n\n---\n\n## SEO Keywords\n\nRSI divergence detector, RSI hidden divergence, Wilder RSI Python, RSI Wilder smoothing, RSI divergence Python library, SciPy find_peaks RSI, RSI divergence CLI, regular vs hidden divergence, price oscillator divergence, RSI 30/70 heuristic, pandas RSI, quantitative trading divergence, Python technical analysis.\n\n",
    "bugtrack_url": null,
    "license": "BSD-3-Clause",
    "summary": "A tool to detect RSI divergences in price data.",
    "version": "0.1.0",
    "project_urls": {
        "Repository": "https://github.com/AKzar1el/rsi_divergence_detector"
    },
    "split_keywords": [
        "rsi",
        " divergence",
        " finance",
        " trading",
        " technical-analysis"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "36f540d322b507455b2dd0c0e8852ebcbfd4e0b9440c57160fa1a29df21ad031",
                "md5": "594a8972ee59127e67b8026cdc8fbd95",
                "sha256": "e5129f9d58f30a4a15640cf5e493775876e20bf82b81accee69fa11c54d6fb9f"
            },
            "downloads": -1,
            "filename": "rsi_divergence_detector-0.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "594a8972ee59127e67b8026cdc8fbd95",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<3.14,>=3.9",
            "size": 12061,
            "upload_time": "2025-08-11T16:23:54",
            "upload_time_iso_8601": "2025-08-11T16:23:54.018533Z",
            "url": "https://files.pythonhosted.org/packages/36/f5/40d322b507455b2dd0c0e8852ebcbfd4e0b9440c57160fa1a29df21ad031/rsi_divergence_detector-0.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b1c5a8f65a79464b213adfc32d134d549a03b9b8b624e0bc34c48fe6473f5878",
                "md5": "75a0b186693f7ca7365b54e3cfd94c89",
                "sha256": "a64d020d297f02bb078635865c4723dfd583f6047869b8f444ddf970335520a7"
            },
            "downloads": -1,
            "filename": "rsi_divergence_detector-0.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "75a0b186693f7ca7365b54e3cfd94c89",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<3.14,>=3.9",
            "size": 14169,
            "upload_time": "2025-08-11T16:23:55",
            "upload_time_iso_8601": "2025-08-11T16:23:55.275885Z",
            "url": "https://files.pythonhosted.org/packages/b1/c5/a8f65a79464b213adfc32d134d549a03b9b8b624e0bc34c48fe6473f5878/rsi_divergence_detector-0.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-11 16:23:55",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "AKzar1el",
    "github_project": "rsi_divergence_detector",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "rsi-divergence-detector"
}
        
Elapsed time: 0.45672s